diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 0e42635244..437c72ca75 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -38,6 +38,7 @@ src/ML-HDNNP/* @singraber src/ML-IAP/* @athomps src/ML-PACE/* @yury-lysogorskiy src/ML-POD/* @exapde +src/ML-UF3/* @monk-04 src/MOFFF/* @hheenen src/MOLFILE/* @akohlmey src/NETCDF/* @pastewka diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index f87c92396f..def26bdfed 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -285,6 +285,7 @@ set(STANDARD_PACKAGES ML-RANN ML-SNAP ML-POD + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/cmake/presets/all_off.cmake b/cmake/presets/all_off.cmake index e078879f70..c82eb568bf 100644 --- a/cmake/presets/all_off.cmake +++ b/cmake/presets/all_off.cmake @@ -60,6 +60,7 @@ set(ALL_PACKAGES ML-QUIP ML-RANN ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/cmake/presets/all_on.cmake b/cmake/presets/all_on.cmake index 3f44a863f7..d909b6aca7 100644 --- a/cmake/presets/all_on.cmake +++ b/cmake/presets/all_on.cmake @@ -62,6 +62,7 @@ set(ALL_PACKAGES ML-QUIP ML-RANN ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/cmake/presets/mingw-cross.cmake b/cmake/presets/mingw-cross.cmake index f3565668b2..8fdce0512f 100644 --- a/cmake/presets/mingw-cross.cmake +++ b/cmake/presets/mingw-cross.cmake @@ -50,6 +50,7 @@ set(WIN_PACKAGES ML-POD ML-RANN ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/cmake/presets/most.cmake b/cmake/presets/most.cmake index 2356e24764..2ed7cbcaac 100644 --- a/cmake/presets/most.cmake +++ b/cmake/presets/most.cmake @@ -45,6 +45,7 @@ set(ALL_PACKAGES ML-IAP ML-POD ML-SNAP + ML-UF3 MOFFF MOLECULE OPENMP diff --git a/cmake/presets/windows.cmake b/cmake/presets/windows.cmake index 9655134e7f..d47e1077e8 100644 --- a/cmake/presets/windows.cmake +++ b/cmake/presets/windows.cmake @@ -42,6 +42,7 @@ set(WIN_PACKAGES ML-IAP ML-POD ML-SNAP + ML-UF3 MOFFF MOLECULE MOLFILE diff --git a/doc/src/Commands_pair.rst b/doc/src/Commands_pair.rst index 577c037e53..984fc5997e 100644 --- a/doc/src/Commands_pair.rst +++ b/doc/src/Commands_pair.rst @@ -303,6 +303,7 @@ OPT. * :doc:`tip4p/long/soft (o) ` * :doc:`tri/lj ` * :doc:`ufm (got) ` + * :doc:`uf3 (k) ` * :doc:`vashishta (gko) ` * :doc:`vashishta/table (o) ` * :doc:`wf/cut ` diff --git a/doc/src/Packages_details.rst b/doc/src/Packages_details.rst index a3d65d9d65..1ac8818c42 100644 --- a/doc/src/Packages_details.rst +++ b/doc/src/Packages_details.rst @@ -84,6 +84,7 @@ page gives those details. * :ref:`ML-QUIP ` * :ref:`ML-RANN ` * :ref:`ML-SNAP ` + * :ref:`ML-UF3 ` * :ref:`MOFFF ` * :ref:`MOLECULE ` * :ref:`MOLFILE ` @@ -1925,6 +1926,31 @@ computes which analyze attributes of the potential. ---------- +.. _PKG-ML-UF3: + +ML-UF3 package +-------------- + +**Contents:** + +A pair style for the ultra-fast force field potentials (UF3). UF3 is a +methodology for deriving a highly accurate classical potential which is +fast to evaluate and is fitted to a large archives of quantum mechanical +(DFT) data. The use of b-spline basis set in UF3 enables the rapid +evaluation of 2-body and 3-body interactions. + +**Authors:** Ajinkya C Hire (University of Florida), +Hendrik Krass (University of Constance), +Matthias Rupp (Luxembourg Institute of Science and Technology), +Richard Hennig (University of Florida) + +**Supporting info:** + +* src/ML-UF3: filenames -> commands +* :doc:`pair_style uf3 ` +* examples/uf3 +* https://github.com/uf3/uf3 + .. _PKG-MOFFF: MOFFF package diff --git a/doc/src/Packages_list.rst b/doc/src/Packages_list.rst index c0a1164513..2fd4086452 100644 --- a/doc/src/Packages_list.rst +++ b/doc/src/Packages_list.rst @@ -318,6 +318,11 @@ whether an extra library is needed to build and use the package: - :doc:`pair_style snap ` - snap - no + * - :ref:`ML-UF3 ` + - quantum-fitted ultra fast potentials + - :doc:`pair_style uf3 ` + - PACKAGES/uf3 + - no * - :ref:`MOFFF ` - styles for `MOF-FF `_ force field - :doc:`pair_style buck6d/coul/gauss ` diff --git a/doc/src/pair_style.rst b/doc/src/pair_style.rst index 13dd922043..b7796b216b 100644 --- a/doc/src/pair_style.rst +++ b/doc/src/pair_style.rst @@ -383,6 +383,7 @@ accelerated styles exist. * :doc:`tracker ` - monitor information about pairwise interactions * :doc:`tri/lj ` - LJ potential between triangles * :doc:`ufm ` - +* :doc:`uf3 ` - UF3 machine-learning potential * :doc:`vashishta ` - Vashishta 2-body and 3-body potential * :doc:`vashishta/table ` - * :doc:`wf/cut ` - Wang-Frenkel Potential for short-ranged interactions diff --git a/doc/src/pair_uf3.rst b/doc/src/pair_uf3.rst new file mode 100644 index 0000000000..ce07e2206f --- /dev/null +++ b/doc/src/pair_uf3.rst @@ -0,0 +1,213 @@ +.. index:: pair_style uf3 +.. index:: pair_style uf3/kk + +pair_style uf3 command +====================== + +Accelerator Variants: *uf3/kk* + +Syntax +"""""" + +.. code-block:: LAMMPS + + pair_style style BodyFlag + +* style = *uf3* or *uf3/kk* + + .. parsed-literal:: + + BodyFlag = Indicates whether to calculate only 2-body or 2 and 3-body interactions. Possible values: 2 or 3 + +Examples +"""""""" + +.. code-block:: LAMMPS + + pair_style uf3 3 + pair_coeff * * Nb.uf3 Nb + + pair_style uf3 2 + pair_coeff * * NbSn.uf3 Nb Sn + + pair_style uf3 3 + pair_coeff * * NbSn.uf3 Nb Sn + +Description +""""""""""" + +.. versionadded:: TBD + +The *uf3* style computes the :ref:`Ultra-Fast Force Fields (UF3) +` potential, a machine-learning interatomic potential. In UF3, +the total energy of the system is defined via two- and three-body +interactions: + +.. math:: + + E & = \sum_{i,j} V_2(r_{ij}) + \sum_{i,j,k} V_3 (r_{ij},r_{ik},r_{jk}) \\ + V_2(r_{ij}) & = \sum_{n=0}^N c_n B_n(r_{ij}) \\ + V_3 (r_{ij},r_{ik},r_{jk}) & = \sum_{l=0}^{N_l} \sum_{m=0}^{N_m} \sum_{n=0}^{N_n} c_{l,m,n} B_l(r_{ij}) B_m(r_{ik}) B_n(r_{jk}) + +where :math:`V_2(r_{ij})` and :math:`V_3 (r_{ij},r_{ik},r_{jk})` are the +two- and three-body interactions, respectively. For the two-body the +summation is over all neighbors J and for the three-body the summation +is over all neighbors J and K of atom I within a cutoff distance +determined from the potential files. :math:`B_n(r_{ij})` are the cubic +b-spline basis, :math:`c_n` and :math:`c_{l,m,n}` are the machine-learned +interaction parameters and :math:`N`, :math:`N_l`, :math:`N_m`, and +:math:`N_n` denote the number of basis functions per spline or tensor +spline dimension. + +With *uf3* style only a single pair_coeff command is used to indicate the +UF3 LAMMPS potential file containing all the two- and three-body interactions +followed by N additional arguments specifying the mapping of UF3 elements to +LAMMPS atom types, where N is the number of LAMMPS atom types: + +* UF3 LAMMPS potential file +* N elements names = mapping of UF3 elements to atom types + +As an example, if a LAMMPS simulation contains 2 atom types (elements +'A' and 'B'), the pair_coeff command will be: + +.. code-block:: LAMMPS + + pair_style uf3 3 + pair_coeff * * AB.uf3 A B + +The AB.uf3 file should contain all two-body (A-A, A-B, B-B) and three-body +(A-A-A, A-A-B, A-B-B, B-A-A, B-A-B, B-B-B). + +If a value of "2" is specified in the :code:`pair_style uf3` command, +only the two-body potentials are needed. For 3-body interaction the +first atom type is the central atom. We recommend using the +:code:`generate_uf3_lammps_pots.py` script (found `here +`_) for +generating the UF3 LAMMPS potential file from the UF3 JSON potentials. + +---------- + +UF3 LAMMPS potential file in the *potentials* directory of the LAMMPS +distribution have a ".uf3" suffix. The interaction block in UF3 LAMMPS potential +file should start with :code:`#UF3 POT` and end with :code:`#` characters. +Following shows the format of a generic 2-body and 3-body potential block in +UF3 LAMMPS potential file- + +.. code-block:: LAMMPS + + #UF3 POT UNITS: units DATE: POT_GEN_DATE AUTHOR: AUTHOR_NAME CITATION: CITE + 2B ELEMENT1 ELEMENT2 LEADING_TRIM TRAILING_TRIM + Rij_CUTOFF NUM_OF_KNOTS + BSPLINE_KNOTS + NUM_OF_COEFF + COEFF + # + #UF3 POT UNITS: units DATE: POT_GEN_DATE AUTHOR: AUTHOR_NAME CITATION: CITE + 3B ELEMENT1 ELEMENT2 ELEMENT3 LEADING_TRIM TRAILING_TRIM + Rjk_CUTOFF Rik_CUTOFF Rij_CUTOFF NUM_OF_KNOTS_JK NUM_OF_KNOTS_IK NUM_OF_KNOTS_IJ + BSPLINE_KNOTS_FOR_JK + BSPLINE_KNOTS_FOR_IK + BSPLINE_KNOTS_FOR_IJ + SHAPE_OF_COEFF_MATRIX[I][J][K] + COEFF_MATRIX[0][0][K] + COEFF_MATRIX[0][1][K] + COEFF_MATRIX[0][2][K] + . + . + . + COEFF_MATRIX[1][0][K] + COEFF_MATRIX[1][1][K] + COEFF_MATRIX[1][2][K] + . + . + . + # + +The second line indicates whether the block contains data for 2-body +(:code:`2B`) or 3-body (:code:`3B`) interaction. This is followed by element +combination interaction, :code:`LEADING_TRIM` and :code:`TRAILING_TRIM` +number on the same line. The current implementation is only tested for +:code:`LEADING_TRIM=0` and :code:`TRAILING_TRIM=3`. +If other values are used LAMMPS is terminated after issuing an error message. +The :code:`Rij_CUTOFF` sets the 2-body cutoff for the interaction described +by the potential block. :code:`NUM_OF_KNOTS` is the number of knots +(or the length of the knot vector) present on the very next line. The +:code:`BSPLINE_KNOTS` line should contain all the knots in ascending order. +:code:`NUM_OF_COEFF` is the number of coefficients in the :code:`COEFF` line. +All the numbers in the BSPLINE_KNOTS and COEFF line should be space-separated. +Similar to the 2-body potential block, the third line sets the cutoffs and +length of the knots. The cutoff distance between atom-type I and J is +:code:`Rij_CUTOFF`, atom-type I and K is :code:`Rik_CUTOFF` and between +J and K is :code:`Rjk_CUTOFF`. + +.. note:: + + The current implementation only works for UF3 potentials with cutoff + distances for 3-body interactions that follows + :code:`2Rij_CUTOFF=2Rik_CUTOFF=Rjk_CUTOFF` relation. + +The :code:`BSPLINE_KNOTS_FOR_JK`, :code:`BSPLINE_KNOTS_FOR_IK`, and +:code:`BSPLINE_KNOTS_FOR_IJ` lines (note the order) contain the knots in +increasing order for atoms J and K, I and K, and atoms I and J +respectively. The number of knots is defined by the +:code:`NUM_OF_KNOTS_*` characters in the previous line. The shape of +the coefficient matrix is defined on the +:code:`SHAPE_OF_COEFF_MATRIX[I][J][K]` line followed by the columns of +the coefficient matrix, one per line, as shown above. For example, if +the coefficient matrix has the shape of 8x8x13, then +:code:`SHAPE_OF_COEFF_MATRIX[I][J][K]` will be :code:`8 8 13` followed +by 64 (8x8) lines each containing 13 coefficients separated by space. + +---------- + +.. include:: accel_styles.rst + +---------- + +Mixing, shift, table, tail correction, restart, rRESPA info +""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + +For atom type pairs I,J and I != J, where types I and J correspond to +two different element types, mixing is performed by LAMMPS as described +above from values in the potential file. + +This pair style does not support the :doc:`pair_modify ` +shift, table, and tail options. + +This pair style does not write its information to :doc:`binary restart +files `, since it is stored in potential file. + +This pair style can only be used via the *pair* keyword of the +:doc:`run_style respa ` command. It does not support the +*inner*, *middle*, *outer* keywords. + +Restrictions +"""""""""""" + +The 'uf3' pair style is part of the ML-UF3 package. It is only enabled +if LAMMPS was built with that package. See the :doc:`Build package +` page for more info. + +This pair style requires the :doc:`newton ` setting to be "on". + +The UF3 LAMMPS potential file provided with LAMMPS (see the potentials +directory) are parameterized for metal :doc:`units `. + +The single() function of 'uf3' pair style only return the 2-body +interaction energy. + +Related commands +"""""""""""""""" + +:doc:`pair_coeff ` + +Default +""""""" + +none + +---------- + +.. _Xie23: + +**(Xie23)** Xie, S.R., Rupp, M. & Hennig, R.G. Ultra-fast interpretable machine-learning potentials. npj Comput Mater 9, 162 (2023). https://doi.org/10.1038/s41524-023-01092-7 diff --git a/doc/utils/sphinx-config/false_positives.txt b/doc/utils/sphinx-config/false_positives.txt index cf98475098..536c7f7ae3 100644 --- a/doc/utils/sphinx-config/false_positives.txt +++ b/doc/utils/sphinx-config/false_positives.txt @@ -1434,6 +1434,7 @@ Hendrik Henin Henkelman Henkes +Hennig henrich Henrich Hermitian @@ -1595,6 +1596,7 @@ interlayer intermolecular interoperable Interparticle +interpretable interstitials intertube Intr @@ -1817,6 +1819,7 @@ Koziol Kp kradius Kraker +Krass Kraus Kremer Kress @@ -3271,6 +3274,7 @@ Rudranarayan Rudzinski Runge runtime +Rupp Rutuparna rx rxd @@ -3820,6 +3824,8 @@ uChem uCond uef UEF +uf +uf3 ufm Uhlenbeck Ui diff --git a/examples/PACKAGES/uf3/Nb.uf3 b/examples/PACKAGES/uf3/Nb.uf3 new file mode 120000 index 0000000000..cb0fdd480d --- /dev/null +++ b/examples/PACKAGES/uf3/Nb.uf3 @@ -0,0 +1 @@ +../../../potentials/Nb.uf3 \ No newline at end of file diff --git a/examples/PACKAGES/uf3/in.uf3.Nb b/examples/PACKAGES/uf3/in.uf3.Nb new file mode 100644 index 0000000000..19b37ccc0b --- /dev/null +++ b/examples/PACKAGES/uf3/in.uf3.Nb @@ -0,0 +1,46 @@ +# Demonstrate UF3 W potential + +# # ============= Initialize simulation + +variable nsteps index 100 +variable nrep equal 4 +variable a equal 3.3005 +units metal + +# generate the box and atom positions using a BCC lattice + +variable nx equal ${nrep} +variable ny equal ${nrep} +variable nz equal ${nrep} + +boundary p p p + +lattice bcc $a +region box block 0 ${nx} 0 ${ny} 0 ${nz} +create_box 1 box +create_atoms 1 box + +mass 1 92.906 + +# # ============= set pair style + +pair_style uf3 3 +pair_coeff * * Nb.uf3 Nb + + +# # ============= Setup output + +thermo 10 +thermo_modify norm yes + +# # ============= Set up NVE run + +timestep 0.5e-3 +neighbor 1.0 bin +neigh_modify once no every 1 delay 0 check yes + +# # ============= Run MD + +velocity all create 300.0 2367804 loop geom +fix 1 all nve +run ${nsteps} diff --git a/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.1 b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.1 new file mode 100644 index 0000000000..0c9c0bffa2 --- /dev/null +++ b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.1 @@ -0,0 +1,118 @@ +LAMMPS (17 Apr 2024 - Development - patch_17Apr2024-199-g49f20229ad-modified) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Demonstrate UF3 W potential + +# # ============= Initialize simulation + +variable nsteps index 100 +variable nrep equal 4 +variable a equal 3.3005 +units metal + +# generate the box and atom positions using a BCC lattice + +variable nx equal ${nrep} +variable nx equal 4 +variable ny equal ${nrep} +variable ny equal 4 +variable nz equal ${nrep} +variable nz equal 4 + +boundary p p p + +lattice bcc $a +lattice bcc 3.3005 +Lattice spacing in x,y,z = 3.3005 3.3005 3.3005 +region box block 0 ${nx} 0 ${ny} 0 ${nz} +region box block 0 4 0 ${ny} 0 ${nz} +region box block 0 4 0 4 0 ${nz} +region box block 0 4 0 4 0 4 +create_box 1 box +Created orthogonal box = (0 0 0) to (13.202 13.202 13.202) + 1 by 1 by 1 MPI processor grid +create_atoms 1 box +Created 128 atoms + using lattice units in orthogonal box = (0 0 0) to (13.202 13.202 13.202) + create_atoms CPU = 0.000 seconds + +mass 1 92.906 + +# # ============= set pair style + +pair_style uf3 3 +pair_coeff * * Nb.uf3 Nb +Reading potential file Nb.uf3 with DATE: 2024-04-02 + + +# # ============= Setup output + +thermo 10 +thermo_modify norm yes + +# # ============= Set up NVE run + +timestep 0.5e-3 +neighbor 1.0 bin +neigh_modify once no every 1 delay 0 check yes + +# # ============= Run MD + +velocity all create 300.0 2367804 loop geom +fix 1 all nve +run ${nsteps} +run 100 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 9 + ghost atom cutoff = 9 + binsize = 4.5, bins = 3 3 3 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair uf3, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.376 | 3.376 | 3.376 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 300 -4.4256832 0 -4.3872081 90756.437 + 10 294.36659 -4.4249607 0 -4.3872081 91006.427 + 20 277.9021 -4.422849 0 -4.387208 91716.126 + 30 251.88303 -4.4195119 0 -4.3872078 92789.12 + 40 218.42803 -4.4152211 0 -4.3872076 94118.45 + 50 180.40641 -4.4103445 0 -4.3872073 95579.009 + 60 141.2326 -4.4053202 0 -4.3872071 97031.816 + 70 104.54429 -4.4006146 0 -4.3872068 98332.882 + 80 73.787889 -4.3966699 0 -4.3872066 99351.332 + 90 51.759956 -4.3938446 0 -4.3872064 99992.934 + 100 40.209821 -4.3923633 0 -4.3872064 100211.98 +Loop time of 0.385575 on 1 procs for 100 steps with 128 atoms + +Performance: 11.204 ns/day, 2.142 hours/ns, 259.353 timesteps/s, 33.197 katom-step/s +99.7% CPU use with 1 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.38403 | 0.38403 | 0.38403 | 0.0 | 99.60 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0.00090609 | 0.00090609 | 0.00090609 | 0.0 | 0.23 +Output | 0.00017626 | 0.00017626 | 0.00017626 | 0.0 | 0.05 +Modify | 0.00018204 | 0.00018204 | 0.00018204 | 0.0 | 0.05 +Other | | 0.0002795 | | | 0.07 + +Nlocal: 128 ave 128 max 128 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Nghost: 1601 ave 1601 max 1601 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 1 0 0 0 0 0 0 0 0 0 +FullNghs: 21504 ave 21504 max 21504 min +Histogram: 1 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 21504 +Ave neighs/atom = 168 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.4 b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.4 new file mode 100644 index 0000000000..cd46d8da14 --- /dev/null +++ b/examples/PACKAGES/uf3/log.13May24.Nb.uf3.g++.4 @@ -0,0 +1,118 @@ +LAMMPS (17 Apr 2024 - Development - patch_17Apr2024-199-g49f20229ad-modified) +OMP_NUM_THREADS environment is not set. Defaulting to 1 thread. (src/comm.cpp:98) + using 1 OpenMP thread(s) per MPI task +# Demonstrate UF3 W potential + +# # ============= Initialize simulation + +variable nsteps index 100 +variable nrep equal 4 +variable a equal 3.3005 +units metal + +# generate the box and atom positions using a BCC lattice + +variable nx equal ${nrep} +variable nx equal 4 +variable ny equal ${nrep} +variable ny equal 4 +variable nz equal ${nrep} +variable nz equal 4 + +boundary p p p + +lattice bcc $a +lattice bcc 3.3005 +Lattice spacing in x,y,z = 3.3005 3.3005 3.3005 +region box block 0 ${nx} 0 ${ny} 0 ${nz} +region box block 0 4 0 ${ny} 0 ${nz} +region box block 0 4 0 4 0 ${nz} +region box block 0 4 0 4 0 4 +create_box 1 box +Created orthogonal box = (0 0 0) to (13.202 13.202 13.202) + 1 by 2 by 2 MPI processor grid +create_atoms 1 box +Created 128 atoms + using lattice units in orthogonal box = (0 0 0) to (13.202 13.202 13.202) + create_atoms CPU = 0.001 seconds + +mass 1 92.906 + +# # ============= set pair style + +pair_style uf3 3 +pair_coeff * * Nb.uf3 Nb +Reading potential file Nb.uf3 with DATE: 2024-04-02 + + +# # ============= Setup output + +thermo 10 +thermo_modify norm yes + +# # ============= Set up NVE run + +timestep 0.5e-3 +neighbor 1.0 bin +neigh_modify once no every 1 delay 0 check yes + +# # ============= Run MD + +velocity all create 300.0 2367804 loop geom +fix 1 all nve +run ${nsteps} +run 100 +Neighbor list info ... + update: every = 1 steps, delay = 0 steps, check = yes + max neighbors/atom: 2000, page size: 100000 + master list distance cutoff = 9 + ghost atom cutoff = 9 + binsize = 4.5, bins = 3 3 3 + 1 neighbor lists, perpetual/occasional/extra = 1 0 0 + (1) pair uf3, perpetual + attributes: full, newton on + pair build: full/bin/atomonly + stencil: full/bin/3d + bin: standard +Per MPI rank memory allocation (min/avg/max) = 3.351 | 3.351 | 3.351 Mbytes + Step Temp E_pair E_mol TotEng Press + 0 300 -4.4256832 0 -4.3872081 90756.437 + 10 294.36659 -4.4249607 0 -4.3872081 91006.427 + 20 277.9021 -4.422849 0 -4.387208 91716.126 + 30 251.88303 -4.4195119 0 -4.3872078 92789.12 + 40 218.42803 -4.4152211 0 -4.3872076 94118.45 + 50 180.40641 -4.4103445 0 -4.3872073 95579.009 + 60 141.2326 -4.4053202 0 -4.3872071 97031.816 + 70 104.54429 -4.4006146 0 -4.3872068 98332.882 + 80 73.787889 -4.3966699 0 -4.3872066 99351.332 + 90 51.759956 -4.3938446 0 -4.3872064 99992.934 + 100 40.209821 -4.3923633 0 -4.3872064 100211.98 +Loop time of 0.11881 on 4 procs for 100 steps with 128 atoms + +Performance: 36.361 ns/day, 0.660 hours/ns, 841.679 timesteps/s, 107.735 katom-step/s +99.3% CPU use with 4 MPI tasks x 1 OpenMP threads + +MPI task timing breakdown: +Section | min time | avg time | max time |%varavg| %total +--------------------------------------------------------------- +Pair | 0.10673 | 0.10875 | 0.11236 | 0.7 | 91.53 +Neigh | 0 | 0 | 0 | 0.0 | 0.00 +Comm | 0.0057324 | 0.0093477 | 0.011375 | 2.4 | 7.87 +Output | 0.00016629 | 0.00018236 | 0.00022483 | 0.0 | 0.15 +Modify | 9.4948e-05 | 0.00010621 | 0.00012066 | 0.0 | 0.09 +Other | | 0.0004263 | | | 0.36 + +Nlocal: 32 ave 32 max 32 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Nghost: 1049 ave 1049 max 1049 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +Neighs: 0 ave 0 max 0 min +Histogram: 4 0 0 0 0 0 0 0 0 0 +FullNghs: 5376 ave 5376 max 5376 min +Histogram: 4 0 0 0 0 0 0 0 0 0 + +Total # of neighbors = 21504 +Ave neighs/atom = 168 +Neighbor list builds = 0 +Dangerous builds = 0 +Total wall time: 0:00:00 diff --git a/potentials/Nb.uf3 b/potentials/Nb.uf3 new file mode 100644 index 0000000000..5f1cdb6f63 --- /dev/null +++ b/potentials/Nb.uf3 @@ -0,0 +1,136 @@ +#UF3 POT UNITS: metal DATE: 2024-04-02 12:18:15.359106 AUTHOR: Ajinkya_Hire CITATION: +2B Nb Nb 0 3 nk +8.0 31 +0.001 0.001 0.001 0.001 0.33429166666666665 0.66758333333333331 1.000875 1.3341666666666665 1.6674583333333333 2.00075 2.3340416666666663 2.6673333333333331 3.0006249999999999 3.3339166666666666 3.667208333333333 4.0004999999999997 4.3337916666666665 4.6670833333333333 5.000375 5.3336666666666668 5.6669583333333335 6.0002500000000003 6.3335416666666671 6.6668333333333338 7.0001249999999997 7.3334166666666665 7.6667083333333332 8 8 8 8 +27 +79.140244588519465 79.140244588519465 55.85833391113556 36.597903318706138 21.358952811231141 12.290000872768841 1.9593931914091953 -0.65697974623243804 -0.85177956270573463 -0.68929688239869991 -0.46787243412973262 -0.27624655899523165 -0.11912921944351409 -0.056302369393035338 -0.0049812809608429064 0.0085637634684603507 0.0034716161454604712 -0.0058751075573311978 -0.005453415412748467 -0.0015123194244718201 0.0011577919587182201 0.001583772506713282 -0.00049823976100720228 -0.0013902809146717273 0 0 0 +# +#UF3 POT UNITS: metal DATE: 2024-04-02 12:18:15.359106 AUTHOR: Ajinkya_Hire CITATION: +3B Nb Nb Nb 0 3 nk +8.0 4.0 4.0 23 15 15 +0.001 0.001 0.001 0.001 0.50093749999999992 1.000875 1.5008124999999999 2.00075 2.5006874999999997 3.0006249999999999 3.5005624999999996 4.0004999999999997 4.5004375000000003 5.000375 5.5003124999999997 6.0002500000000003 6.5001875 7.0001249999999997 7.5000625000000003 8 8 8 8 +0.001 0.001 0.001 0.001 0.50087499999999996 1.00075 1.5006249999999999 2.0005000000000002 2.500375 3.0002499999999999 3.5001250000000002 4 4 4 4 +0.001 0.001 0.001 0.001 0.50087499999999996 1.00075 1.5006249999999999 2.0005000000000002 2.500375 3.0002499999999999 3.5001250000000002 4 4 4 4 +11 11 19 +-1.1790416072105636e-06 6.589114265858035e-08 2.1094970065385374e-06 4.7014910818419987e-07 8.288423734406254e-06 0.000186151370764668 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +3.2366723157260956e-05 2.6208783380066457e-05 1.0239981836366566e-05 1.8487993936404763e-05 2.1943710009352506e-05 2.6899947783571087e-07 5.002786118380638e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.0696915445106504e-05 6.184559535738335e-05 5.870203846064511e-05 -1.112085789465658e-05 -4.7600144351359347e-07 -5.861397594145908e-08 1.4524208784805573e-08 2.300649782987421e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +5.282737863089323e-05 6.328946161646202e-06 1.8329325276370316e-05 1.6423572667388823e-05 1.2653184610977003e-06 7.181714140248046e-06 3.491501462345434e-06 -7.285463619241614e-06 3.2609159022388403e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6.9413198850914024e-06 2.107626397843018e-05 1.8155172114721186e-05 2.0928626557075606e-06 1.5632037328512312e-06 -2.7335717313450097e-07 -7.2126792356200426e-09 9.213093725547886e-09 4.186629643010996e-08 8.198811769753182e-08 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +1.4231393739579515e-06 3.630746449160232e-07 9.318604659023228e-07 4.92311430374376e-07 -3.701479331898353e-09 2.1280257031614452e-07 1.2240989510544568e-06 5.3432540178806065e-06 2.043230389835189e-06 3.2740024159475547e-07 6.717304982644579e-07 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 5.196157077391817e-07 6.938124100654148e-08 7.597564197383545e-08 1.863740632660483e-07 4.437837629589167e-07 5.453941063185757e-07 1.5602917821833568e-06 3.404289212094662e-07 9.967447994956849e-07 5.8845599651090215e-06 1.5052240335012455e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 3.196534127251379e-06 -1.1872677866681306e-06 -2.5678892066098854e-08 5.139117071436217e-09 1.1142431390092631e-06 2.0605776537608227e-06 5.297265009242829e-06 6.713907186544732e-06 2.7028644452395994e-06 1.149242737988068e-06 2.2449682976927855e-06 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +3.2366723157260956e-05 2.6208783380066457e-05 1.0239981836366566e-05 1.8487993936404763e-05 2.1943710009352506e-05 2.6899947783571087e-07 5.002786118380638e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +9.36844864368356e-06 1.9223644807676324e-05 1.9979026246524356e-05 3.627062812549574e-05 9.775578281629195e-06 -5.894357549683858e-06 6.470814473155067e-07 2.31805322174729e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +2.2218614171918013e-06 5.325319655352672e-06 7.766746363269582e-06 9.361315506075464e-06 5.0417710282874456e-05 9.822946186678772e-05 0.00026400568406806884 0.00033610865151919737 0.00013239814531221768 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.4850777249143735e-05 7.094600012126306e-05 0.00030581781354430576 0.00044661036994300023 0.00016699596636619577 1.5860625743775105e-05 9.74250537001798e-07 5.385650613476577e-06 8.091278451728344e-06 1.2460869401480828e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0001028691918645833 0.0002737040057685444 0.0003861446001781946 0.0004042287651515365 0.0017229200225725174 0.003198296698131205 0.008774096120579751 0.011237818178923189 0.004334800036723805 0.0007344916552783145 -0.0001506915192259342 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-1.2482511756156149e-05 1.365124801275985e-05 1.3894049203809568e-05 2.3985465221727954e-05 3.3458449092465795e-05 0.00028172299406359233 0.00040056109827889085 0.0004621959325200118 0.0034637215474633033 0.009153352872912168 0.012804683731760212 0.010674833967812809 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.005346497059990333 -0.002010348201210142 -0.0010943235863089423 0.0001661513182702165 0.00012025969610516196 2.4949866002221845e-05 6.627236360802077e-06 3.003757825105864e-06 3.997348910159012e-05 0.000427961841918743 0.0007451357800599296 0.0011219432594133996 0.009685550613014016 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.013431011504370738 0.007883426617122005 0.007935899204760883 0.005880150773602205 0.0009832099103910489 0.005414528729313218 0.0015950126575825377 0.00024127039666882992 -1.5674461809944553e-05 1.0711548076574028e-05 7.830483572860064e-06 0.00011012649333888752 0.0005497452692208139 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.0696915445106504e-05 6.184559535738335e-05 5.870203846064511e-05 -1.112085789465658e-05 -4.7600144351359347e-07 -5.861397594145908e-08 1.4524208784805573e-08 2.300649782987421e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +2.2218614171918013e-06 5.325319655352672e-06 7.766746363269582e-06 9.361315506075464e-06 5.0417710282874456e-05 9.822946186678772e-05 0.00026400568406806884 0.00033610865151919737 0.00013239814531221768 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.00013804169495254125 0.0012238504051117233 0.01461439973735456 0.010197731078827295 0.009003775355755566 0.030381456320656558 0.024785731678029766 0.004637019267552505 -0.005938106654005813 -0.002605150959220643 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-0.0002216303488927365 0.0001541319391627563 4.83626397765333e-05 2.1041902272582753e-05 0.00026610797279588076 0.00045665788403242036 0.00017325291338578903 0.0035336618936866277 0.018540440861910777 0.003501320637152642 0.002219074201926699 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.01652594711887213 0.011725805945708163 0.011173124362203699 0.0024178633067081135 -0.01796173780303683 -0.011618890946870497 -0.0008528234196397706 -9.706084806556783e-05 -2.754043401157181e-06 0.0001324948483342069 5.482811058752758e-05 0.0003886706609323921 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.008855607599180339 0.015278371659152929 0.0023879884417463693 0.000935102721182137 0.0034651523786104546 0.005282714096158778 0.0012741283037854573 0.006268847413803995 0.004013755514818873 0.010363477891131097 0.007109323912817858 -0.0002600093944564617 -0.00034633976332068713 0.0 0.0 0.0 0.0 0.0 0.0 +-2.698386662730078e-05 2.754973422173369e-07 0.0001320534807487939 0.004372176148977807 0.0015642026255259442 0.004248632573013906 0.00040885420395593786 0.001088966135412402 0.004766232525411325 0.002205157762668968 0.007459939889093756 0.005587608653898612 -0.004720162133268877 -0.006593174803103767 0.0 0.0 0.0 0.0 0.0 +-7.940872165606751e-05 2.276762148612182e-06 0.00010635762128769112 2.049233578255131e-05 0.00042145671490654473 0.01249692872936893 0.0020370917425772224 0.0017316344055948985 0.0006574004028558345 0.0012283310563930355 0.0014629455315045585 -4.492954039177435e-06 0.00029547002108771967 0.002683727758662211 0.004096710661285439 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +5.282737863089323e-05 6.328946161646202e-06 1.8329325276370316e-05 1.6423572667388823e-05 1.2653184610977003e-06 7.181714140248046e-06 3.491501462345434e-06 -7.285463619241614e-06 3.2609159022388403e-06 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +4.4850777249143735e-05 7.094600012126306e-05 0.00030581781354430576 0.00044661036994300023 0.00016699596636619577 1.5860625743775105e-05 9.74250537001798e-07 5.385650613476577e-06 8.091278451728344e-06 1.2460869401480828e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-0.0002216303488927365 0.0001541319391627563 4.83626397765333e-05 2.1041902272582753e-05 0.00026610797279588076 0.00045665788403242036 0.00017325291338578903 0.0035336618936866277 0.018540440861910777 0.003501320637152642 0.002219074201926699 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.003917873880791907 -0.0007874629498581528 -2.4595030318112164e-05 -2.8508297646329816e-06 1.8504666071760445e-07 0.0001190800388356091 0.0035373487148805376 0.00037674157183609377 0.0012087894330956167 0.0009651695201594091 4.769364472898923e-05 0.0004612591073953361 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.00022640297379380707 -0.0005111351623843819 0.0002024994190007784 0.00044921539785371963 0.001393999756415734 0.0011754659552919043 7.761533188706794e-05 5.8170561410888746e-05 -1.0918989217761552e-05 -2.9455190099531973e-07 2.0845708467284646e-07 1.0072947935068441e-06 2.449241542240889e-06 0.0 0.0 0.0 0.0 0.0 0.0 +5.3159155089314414e-05 1.2012438398909825e-05 3.274115317951001e-05 1.689353008824745e-05 -4.232110203859359e-07 7.656160171407207e-06 5.754938338062256e-05 0.0002687156220968384 9.768544317740195e-05 1.0129360414562531e-05 2.293272526112481e-05 1.8260890221186993e-05 1.7288534885724222e-06 1.8856324749638164e-06 0.0 0.0 0.0 0.0 0.0 +4.542360076931743e-06 1.2329326209575631e-05 1.7173803033436737e-05 5.0102066463061734e-05 1.09067765324765e-05 4.930240898900306e-05 0.00028721835291257015 0.0007503332386451459 0.00015238128535605624 -6.391111549761724e-05 -4.677072820313549e-06 -5.572104125200205e-06 2.707663268609677e-05 5.022846595129856e-05 0.00012970076559689836 0.0 0.0 0.0 0.0 +0.0001650881267658455 6.548635015912796e-05 3.282822556024051e-05 7.205996516588195e-05 0.00030710620226134084 0.0007279352507540159 0.000909918529220897 0.0017257383928761386 0.00047543969768972346 -0.00030462814537952123 2.7321207199326783e-05 0.00010130812246147248 5.4817489360932934e-05 0.00012640103175376577 0.00018995742264027741 0.00023929212126678798 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +6.9413198850914024e-06 2.107626397843018e-05 1.8155172114721186e-05 2.0928626557075606e-06 1.5632037328512312e-06 -2.7335717313450097e-07 -7.2126792356200426e-09 9.213093725547886e-09 4.186629643010996e-08 8.198811769753182e-08 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0001028691918645833 0.0002737040057685444 0.0003861446001781946 0.0004042287651515365 0.0017229200225725174 0.003198296698131205 0.008774096120579751 0.011237818178923189 0.004334800036723805 0.0007344916552783145 -0.0001506915192259342 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.01652594711887213 0.011725805945708163 0.011173124362203699 0.0024178633067081135 -0.01796173780303683 -0.011618890946870497 -0.0008528234196397706 -9.706084806556783e-05 -2.754043401157181e-06 0.0001324948483342069 5.482811058752758e-05 0.0003886706609323921 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.00022640297379380707 -0.0005111351623843819 0.0002024994190007784 0.00044921539785371963 0.001393999756415734 0.0011754659552919043 7.761533188706794e-05 5.8170561410888746e-05 -1.0918989217761552e-05 -2.9455190099531973e-07 2.0845708467284646e-07 1.0072947935068441e-06 2.449241542240889e-06 0.0 0.0 0.0 0.0 0.0 0.0 +0.0016181071043329578 0.003179470547568356 0.008661622548635572 0.011071785334468471 0.004294892778359652 0.0017845979744737465 0.0034643761195723064 0.015112039067322293 0.022192108732694595 0.008134230944897397 0.0007595380961610584 1.6727218309602107e-05 0.00012823915020345735 0.0001971442066043176 0.0 0.0 0.0 0.0 0.0 +0.00033854327480422193 0.0032940012133255356 0.008932075729876752 0.012661798131960687 0.013919159699477152 0.08208818801401566 0.15644219608737447 0.4341503084393359 0.557964838826116 0.21173866865770563 0.03478604116524652 -0.007972916161324952 -0.0007132020154210059 0.0004420932693293155 0.0003860741867263207 0.0 0.0 0.0 0.0 +0.0005943091729493132 0.0009672866630600067 0.009096489467732383 0.01304005169719466 0.01734885651081947 0.1652472792755658 0.44880261475702005 0.6329167707872334 0.5244926606398645 0.26270394857828266 -0.10487776273847933 -0.05845317239353218 0.0032135333670803676 0.003777214235598332 0.0007681993725802362 0.00011959437074006901 0.0 0.0 0.0 +6.489304732024981e-05 0.0011748014116558024 0.014162497237899634 0.024470256017495366 0.046651858009005745 0.46415330969555396 0.6536160620847673 0.38295932353650225 0.39318393240673155 0.2877811024545165 0.03747496490739291 0.2654106688863148 0.074634565935104 0.012330295300167044 -0.0004996457463809098 0.00023089219471653216 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +1.4231393739579515e-06 3.630746449160232e-07 9.318604659023228e-07 4.92311430374376e-07 -3.701479331898353e-09 2.1280257031614452e-07 1.2240989510544568e-06 5.3432540178806065e-06 2.043230389835189e-06 3.2740024159475547e-07 6.717304982644579e-07 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +-1.2482511756156149e-05 1.365124801275985e-05 1.3894049203809568e-05 2.3985465221727954e-05 3.3458449092465795e-05 0.00028172299406359233 0.00040056109827889085 0.0004621959325200118 0.0034637215474633033 0.009153352872912168 0.012804683731760212 0.010674833967812809 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.008855607599180339 0.015278371659152929 0.0023879884417463693 0.000935102721182137 0.0034651523786104546 0.005282714096158778 0.0012741283037854573 0.006268847413803995 0.004013755514818873 0.010363477891131097 0.007109323912817858 -0.0002600093944564617 -0.00034633976332068713 0.0 0.0 0.0 0.0 0.0 0.0 +5.3159155089314414e-05 1.2012438398909825e-05 3.274115317951001e-05 1.689353008824745e-05 -4.232110203859359e-07 7.656160171407207e-06 5.754938338062256e-05 0.0002687156220968384 9.768544317740195e-05 1.0129360414562531e-05 2.293272526112481e-05 1.8260890221186993e-05 1.7288534885724222e-06 1.8856324749638164e-06 0.0 0.0 0.0 0.0 0.0 +0.00033854327480422193 0.0032940012133255356 0.008932075729876752 0.012661798131960687 0.013919159699477152 0.08208818801401566 0.15644219608737447 0.4341503084393359 0.557964838826116 0.21173866865770563 0.03478604116524652 -0.007972916161324952 -0.0007132020154210059 0.0004420932693293155 0.0003860741867263207 0.0 0.0 0.0 0.0 +0.00018639122271027446 0.0034767153815636618 0.018231622622978436 0.0042988446466234575 0.05300133577632108 0.7250033316881788 0.4935009383219143 0.42606157195551264 1.5039118559972142 1.2303936880370434 0.22548363428435172 -0.30298333788301807 -0.13073656424500055 -0.010403074319359695 0.005059645288601829 0.0015181780063355998 0.0 0.0 0.0 +0.0005854549915295117 0.008715343377777027 0.015086646356161998 0.00551449475752511 0.16771008674532747 0.9262472909137329 0.16287454314633398 0.10026082406557575 0.8138824998965698 0.5734788502649438 0.5447903546528722 0.10618098607332271 -0.9103493511412221 -0.576660316279193 -0.03402023384277208 -0.0031478924709104684 0.0 0.0 0.0 +-0.00011090752856021898 0.0043805342288213535 0.0016927729283659975 0.012954305343473369 0.4368797400066579 0.7614408833500013 0.10944765261392181 0.0412051224385603 0.15805652281823218 0.2585893276179897 0.05949650977132904 0.30356693149425945 0.19493804255113664 0.5122323478146567 0.35279041052227494 -0.007488446744915854 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 5.196157077391817e-07 6.938124100654148e-08 7.597564197383545e-08 1.863740632660483e-07 4.437837629589167e-07 5.453941063185757e-07 1.5602917821833568e-06 3.404289212094662e-07 9.967447994956849e-07 5.8845599651090215e-06 1.5052240335012455e-05 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.005346497059990333 -0.002010348201210142 -0.0010943235863089423 0.0001661513182702165 0.00012025969610516196 2.4949866002221845e-05 6.627236360802077e-06 3.003757825105864e-06 3.997348910159012e-05 0.000427961841918743 0.0007451357800599296 0.0011219432594133996 0.009685550613014016 0.0 0.0 0.0 0.0 0.0 0.0 +-2.698386662730078e-05 2.754973422173369e-07 0.0001320534807487939 0.004372176148977807 0.0015642026255259442 0.004248632573013906 0.00040885420395593786 0.001088966135412402 0.004766232525411325 0.002205157762668968 0.007459939889093756 0.005587608653898612 -0.004720162133268877 -0.006593174803103767 0.0 0.0 0.0 0.0 0.0 +4.542360076931743e-06 1.2329326209575631e-05 1.7173803033436737e-05 5.0102066463061734e-05 1.09067765324765e-05 4.930240898900306e-05 0.00028721835291257015 0.0007503332386451459 0.00015238128535605624 -6.391111549761724e-05 -4.677072820313549e-06 -5.572104125200205e-06 2.707663268609677e-05 5.022846595129856e-05 0.00012970076559689836 0.0 0.0 0.0 0.0 +0.0005943091729493132 0.0009672866630600067 0.009096489467732383 0.01304005169719466 0.01734885651081947 0.1652472792755658 0.44880261475702005 0.6329167707872334 0.5244926606398645 0.26270394857828266 -0.10487776273847933 -0.05845317239353218 0.0032135333670803676 0.003777214235598332 0.0007681993725802362 0.00011959437074006901 0.0 0.0 0.0 +0.0005854549915295117 0.008715343377777027 0.015086646356161998 0.00551449475752511 0.16771008674532747 0.9262472909137329 0.16287454314633398 0.10026082406557575 0.8138824998965698 0.5734788502649438 0.5447903546528722 0.10618098607332271 -0.9103493511412221 -0.576660316279193 -0.03402023384277208 -0.0031478924709104684 0.0 0.0 0.0 +-0.011510449622067839 -0.0007610595804959427 1.0172131902385016e-05 0.00448473230635448 0.2199020425072735 0.07466247888373397 0.21339517449435372 0.013531084627798973 0.04473458040783101 0.2378714243611067 0.10478901497777 0.37112701147924365 0.27817806337533985 -0.2385293501359752 -0.33578482057600856 -0.004009555340792723 0.0 0.0 0.0 +4.1934884152796484e-05 0.0035902058234846823 0.0005824017329515572 0.01441762880686721 0.6293209695433368 0.09572421881003676 0.08586090788885907 0.031601835145355577 0.06121858995657405 0.07315778164682188 -0.0013308261229131521 0.012882908917780034 0.13273058077548822 0.2035107778991338 0.1961396131043037 -0.04170252478795313 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 3.196534127251379e-06 -1.1872677866681306e-06 -2.5678892066098854e-08 5.139117071436217e-09 1.1142431390092631e-06 2.0605776537608227e-06 5.297265009242829e-06 6.713907186544732e-06 2.7028644452395994e-06 1.149242737988068e-06 2.2449682976927855e-06 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.013431011504370738 0.007883426617122005 0.007935899204760883 0.005880150773602205 0.0009832099103910489 0.005414528729313218 0.0015950126575825377 0.00024127039666882992 -1.5674461809944553e-05 1.0711548076574028e-05 7.830483572860064e-06 0.00011012649333888752 0.0005497452692208139 0.0 0.0 0.0 0.0 0.0 +-7.940872165606751e-05 2.276762148612182e-06 0.00010635762128769112 2.049233578255131e-05 0.00042145671490654473 0.01249692872936893 0.0020370917425772224 0.0017316344055948985 0.0006574004028558345 0.0012283310563930355 0.0014629455315045585 -4.492954039177435e-06 0.00029547002108771967 0.002683727758662211 0.004096710661285439 0.0 0.0 0.0 0.0 +0.0001650881267658455 6.548635015912796e-05 3.282822556024051e-05 7.205996516588195e-05 0.00030710620226134084 0.0007279352507540159 0.000909918529220897 0.0017257383928761386 0.00047543969768972346 -0.00030462814537952123 2.7321207199326783e-05 0.00010130812246147248 5.4817489360932934e-05 0.00012640103175376577 0.00018995742264027741 0.00023929212126678798 0.0 0.0 0.0 +6.489304732024981e-05 0.0011748014116558024 0.014162497237899634 0.024470256017495366 0.046651858009005745 0.46415330969555396 0.6536160620847673 0.38295932353650225 0.39318393240673155 0.2877811024545165 0.03747496490739291 0.2654106688863148 0.074634565935104 0.012330295300167044 -0.0004996457463809098 0.00023089219471653216 0.0 0.0 0.0 +-0.00011090752856021898 0.0043805342288213535 0.0016927729283659975 0.012954305343473369 0.4368797400066579 0.7614408833500013 0.10944765261392181 0.0412051224385603 0.15805652281823218 0.2585893276179897 0.05949650977132904 0.30356693149425945 0.19493804255113664 0.5122323478146567 0.35279041052227494 -0.007488446744915854 0.0 0.0 0.0 +4.1934884152796484e-05 0.0035902058234846823 0.0005824017329515572 0.01441762880686721 0.6293209695433368 0.09572421881003676 0.08586090788885907 0.031601835145355577 0.06121858995657405 0.07315778164682188 -0.0013308261229131521 0.012882908917780034 0.13273058077548822 0.2035107778991338 0.1961396131043037 -0.04170252478795313 0.0 0.0 0.0 +-0.0008465335016788498 -9.208409992139663e-05 -1.1210629044433908e-05 0.004300763141885697 0.1800503541691201 0.016819879476467067 0.060737350690215776 0.042330087306607714 0.0007006095666399378 0.02251352126872946 0.011185142175963118 -0.02716513333374441 0.00952941322650142 0.02210443704516212 0.07011148238258197 0.057840211345517194 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 +# diff --git a/potentials/README b/potentials/README index 2cb4a383c5..2d6d4c172a 100644 --- a/potentials/README +++ b/potentials/README @@ -118,4 +118,5 @@ sw Stillinger-Weber potential tersoff Tersoff potential tersoff.mod modified Tersoff potential tersoff.zbl Tersoff with ZBL core +uf3 UF3 potential vashishta Vashishta 2-body and 3-body potential diff --git a/src/.gitignore b/src/.gitignore index b145f81159..cd82081c35 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -169,6 +169,17 @@ /rann_*.cpp /rann_*.h +/pair_uf3.cpp +/pair_uf3.h +/uf3_bspline_basis2.cpp +/uf3_bspline_basis2.h +/uf3_bspline_basis3.cpp +/uf3_bspline_basis3.h +/uf3_pair_bspline.cpp +/uf3_pair_bspline.h +/uf3_triplet_bspline.cpp +/uf3_triplet_bspline.h + /compute_test_nbl.cpp /compute_test_nbl.h /pair_multi_lucy.cpp diff --git a/src/KOKKOS/pair_uf3_kokkos.cpp b/src/KOKKOS/pair_uf3_kokkos.cpp new file mode 100644 index 0000000000..4a3bcc164b --- /dev/null +++ b/src/KOKKOS/pair_uf3_kokkos.cpp @@ -0,0 +1,1661 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#include "pair_uf3.h" +#include "pair_uf3_kokkos.h" + +#include "atom_kokkos.h" +#include "atom_masks.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "kokkos.h" +#include "kokkos_type.h" +#include "math_const.h" +#include "math_special_kokkos.h" +#include "memory.h" +#include "memory_kokkos.h" +#include "neigh_list_kokkos.h" +#include "neigh_request.h" +#include "neighbor.h" +#include "pair_kokkos.h" +#include "text_file_reader.h" + +#include +#include +#include + +using namespace LAMMPS_NS; +using namespace MathConst; +using MathSpecialKokkos::cube; +using MathSpecialKokkos::square; + +template PairUF3Kokkos::PairUF3Kokkos(LAMMPS *lmp) : PairUF3(lmp) +{ + respa_enable = 0; + + //kokkosable = 1; + atomKK = (AtomKokkos *) atom; + execution_space = ExecutionSpaceFromDevice::space; + datamask_read = X_MASK | F_MASK | TAG_MASK | TYPE_MASK | ENERGY_MASK | VIRIAL_MASK; + datamask_modify = F_MASK | ENERGY_MASK | VIRIAL_MASK; + +} + +template PairUF3Kokkos::~PairUF3Kokkos() +{ + if (!copymode) { + memoryKK->destroy_kokkos(k_eatom, eatom); //destory eatom from host, set it to nullptr + //Also set k_eatom to empty View + memoryKK->destroy_kokkos(k_vatom, vatom); + memoryKK->destroy_kokkos(k_cutsq,cutsq); + destroy_3d(k_cut_3b,cut_3b); + destroy_4d(k_min_cut_3b,min_cut_3b); + eatom = NULL; + vatom = NULL; + cvatom = NULL; + } +} + +template +template +void PairUF3Kokkos::destroy_3d(TYPE data, typename TYPE::value_type*** &array) +{ + if (array == nullptr) return; + data = TYPE(); + memory->sfree(array); + array = nullptr; +} + +template +template +void PairUF3Kokkos::destroy_4d(TYPE data, typename TYPE::value_type**** &array) +{ + if (array == nullptr) return; + data = TYPE(); + memory->sfree(array); + array = nullptr; +} + +/* ---------------------------------------------------------------------- + * global settings + * ---------------------------------------------------------------------- */ + +template void PairUF3Kokkos::settings(int narg, char **arg) +{ + PairUF3::settings(narg, arg); + //1. Determines whether the simulation is 2-body or 2 and 3-body + //2. Set nbody_flag, num_of_elements, pot_3b +} + +/* ---------------------------------------------------------------------- + * set coeffs for one or more type pairs + * ---------------------------------------------------------------------- */ +template void PairUF3Kokkos::coeff(int narg, char **arg) +{ + PairUF3::coeff(narg,arg); + //Also calls allocate internally + //Grows arrays to the right dimensions --> setflag, cutsq, cut, knot_spacing_type_2b, + //knot_spacing_2b, n2b_knots_array_size, n2b_coeff_array_size, setflag_3b, + //cut_3b, cut_3b_list, min_cut_3b, knot_spacing_type_3b, knot_spacing_3b, + //tot_interaction_count_3b, map_3b, n3b_knots_array_size, n3b_coeff_array_size, + //neighshort + // + //Also reads the pot_files_internally + +} + +template +void PairUF3Kokkos::allocate() +{ + if (!allocated) PairUF3::allocate(); + int n = atom->ntypes; + memory->destroy(cutsq); //Why are we destroying cutsq? cutsq is allocated when + //PairUF3::coeff or PairUF3::allocate is called; in the next step when k_cutsq + //is created cutsq is set to point to the host array of k_cutsq + //memory->destroy(cut_3b); + + memoryKK->create_kokkos(k_cutsq,cutsq,n+1,n+1,"pair:cutsq"); + d_cutsq = k_cutsq.template view(); //assignment; get the device + //view of k_cutsq and assign it to d_cutsq; in the header file we just + //decleared d_cutsq's type + memoryKK->create_kokkos(k_cut_3b,n+1,n+1,n+1,"threebody:cut"); + memoryKK->create_kokkos(k_min_cut_3b,n+1,n+1,n+1,3,"threebody:cut"); + d_cut_3b = k_cut_3b.template view(); + d_min_cut_3b = k_min_cut_3b.template view(); +} + + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ + +template void PairUF3Kokkos::init_style() +{ + + PairUF3::init_style(); + + neighflag = lmp->kokkos->neighflag; + + auto request = neighbor->find_request(this); + request->set_kokkos_host(std::is_same::value && + !std::is_same::value); + request->set_kokkos_device(std::is_same::value); + + request->enable_full(); + request->enable_ghost(); +} + +/* ---------------------------------------------------------------------- + init list sets the pointer to full neighbour list requested in previous function +------------------------------------------------------------------------- */ + +template +void PairUF3Kokkos::init_list(int /*id*/, class NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ +template double PairUF3Kokkos::init_one(int i, int j) +{ + double cutone = PairUF3::init_one(i, j); + + if (!coefficients_created) create_coefficients(); + + k_cutsq.h_view(i,j) = k_cutsq.h_view(j,i) = cutone*cutone; //Update the k_cutsq's + //host memory + k_cutsq.template modify(); //Record that k_cutsq's host memory has + //been modified + + return cutone; +} + +template void PairUF3Kokkos::create_coefficients() +{ + const int num_of_elements = atom->ntypes; + coefficients_created = 1; + + if (pot_3b) { + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + k_cut_3b.h_view(i,j,k) = cut_3b[i][j][k]; + + // Notice the order of min_cut_3b[i][j][k] + //In min_cut_3b[i][j][k], + //min_cut_3b[i][j][k][0] is the knot_vector along jk, + //min_cut_3b[i][j][k][1] is the knot_vector along ik, + //min_cut_3b[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + k_min_cut_3b.h_view(i,j,k,0) = min_cut_3b[i][j][k][0]; + k_min_cut_3b.h_view(i,j,k,1) = min_cut_3b[i][j][k][1]; + k_min_cut_3b.h_view(i,j,k,2) = min_cut_3b[i][j][k][2]; + } + } + } + k_cut_3b.template modify(); + k_min_cut_3b.template modify(); + } + + //No allocation on device for --> setflag, cut, knot_spacing_type_2b, + //n2b_knot, n2b_coeff, n2b_knot[i], n2b_coeff[i], setflag_3b, cut_3b, + //cut_3b_list, min_cut_3b, knot_spacing_type_3b, cut_3b_list, n3b_knot_matrix, + //neighshort + + //UFBS2b and UFBS3b are array of objects. Bad idea to use kokkos view(array) + //for it + create_2b_coefficients(); + if (pot_3b) create_3b_coefficients(); + +} + +template void PairUF3Kokkos::create_2b_coefficients() +{ + const int num_of_elements = atom->ntypes; + + // Setup interaction pair map + //TODO: Instead of using map2b and map3b use simple indexing + Kokkos::realloc(map2b, num_of_elements + 1, num_of_elements + 1); + auto map2b_view = Kokkos::create_mirror(map2b); + + int interaction_count = 0; + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + map2b_view(i, j) = interaction_count; + map2b_view(j, i) = interaction_count++; + } + } + Kokkos::deep_copy(map2b, map2b_view); + + // Count max knots for array size + + int max_knots = max_num_knots_2b; + + // Copy coefficients to view + + Kokkos::realloc(d_coefficients_2b, interaction_count, max_knots - 4); + auto d_coefficients_2b_view = Kokkos::create_mirror(d_coefficients_2b); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int k = 0; k < max_num_coeff_2b; k++) { + d_coefficients_2b_view(map2b_view(i, j), k) = n2b_coeff_array[i][j][k]; + } + } + } + Kokkos::deep_copy(d_coefficients_2b, d_coefficients_2b_view); + + // Copy knots from array to view + + Kokkos::realloc(d_n2b_knot, interaction_count, max_knots); + Kokkos::realloc(d_n2b_knot_spacings, interaction_count); + auto d_n2b_knot_view = Kokkos::create_mirror(d_n2b_knot); + auto d_n2b_knot_spacings_view = Kokkos::create_mirror(d_n2b_knot_spacings); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int k = 0; k < max_num_knots_2b; k++) { + d_n2b_knot_view(map2b_view(i, j), k) = n2b_knots_array[i][j][k]; + } + d_n2b_knot_spacings_view(map2b_view(i, j)) = n2b_knots_array[i][j][4] - n2b_knots_array[i][j][3]; + } + } + + Kokkos::deep_copy(d_n2b_knot, d_n2b_knot_view); + Kokkos::deep_copy(d_n2b_knot_spacings, d_n2b_knot_spacings_view); + // Set spline constants + + Kokkos::realloc(constants_2b, interaction_count, max_knots - 4); + auto constants_2b_view = Kokkos::create_mirror(constants_2b); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int l = 0; l < n2b_knots_array_size[i][j] - 4; l++) { + //n2b_knot[i][j].size() - 4; l++) { + auto c = get_constants(&n2b_knots_array[i][j][l], n2b_coeff_array[i][j][l]); + for (int k = 0; k < 16; k++) + constants_2b_view(map2b_view(i, j), l, k) = (std::isinf(c[k]) || std::isnan(c[k])) ? 0 + : c[k]; + } + } + } + Kokkos::deep_copy(constants_2b, constants_2b_view); + + Kokkos::realloc(dnconstants_2b, interaction_count, max_knots - 5); + auto dnconstants_2b_view = Kokkos::create_mirror(dnconstants_2b); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = i; j < num_of_elements + 1; j++) { + for (int l = 0; l < n2b_knots_array_size[i][j] - 5; l++) { + double dntemp4 = 3 / (n2b_knots_array[i][j][l + 4] - n2b_knots_array[i][j][l + 1]); + double coeff = (n2b_coeff_array[i][j][l + 1] - n2b_coeff_array[i][j][l]) * dntemp4; + auto c = get_dnconstants(&n2b_knots_array[i][j][l + 1], coeff); + for (int k = 0; k < 9; k++) + dnconstants_2b_view(map2b_view(i, j), l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + } + } + Kokkos::deep_copy(dnconstants_2b, dnconstants_2b_view); +} + +template void PairUF3Kokkos::create_3b_coefficients() +{ + const int num_of_elements = atom->ntypes; + // Init interaction map for 3B + + Kokkos::realloc(map3b, num_of_elements + 1, num_of_elements + 1, num_of_elements + 1); + auto map3b_view = Kokkos::create_mirror(map3b); + + int interaction_count = 0; + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + map3b_view(i, j, k) = interaction_count; + interaction_count++; + } + } + } + Kokkos::deep_copy(map3b, map3b_view); + + // Count max knots for view + + int max_knots = max_num_knots_3b; + //In n3b_knot_matrix[i][j][k], + //n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + + + // Init knot matrix view + + Kokkos::realloc(d_n3b_knot_matrix, interaction_count, 3, max_knots); + Kokkos::realloc(d_n3b_knot_matrix_spacings, interaction_count, 3); + auto d_n3b_knot_matrix_view = Kokkos::create_mirror(d_n3b_knot_matrix); + auto d_n3b_knot_matrix_spacings_view = Kokkos::create_mirror(d_n3b_knot_matrix_spacings); + + for (int i = 1; i < num_of_elements + 1; i++) + for (int j = 1; j < num_of_elements + 1; j++) + for (int k = 1; k < num_of_elements + 1; k++) { + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][0]; m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 0, m) = + n3b_knots_array[map_3b[i][j][k]][0][m]; + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][1]; m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 1, m) = + n3b_knots_array[map_3b[i][j][k]][1][m]; + for (int m = 0; m < n3b_knots_array_size[map_3b[i][j][k]][2]; m++) + d_n3b_knot_matrix_view(map3b_view(i, j, k), 2, m) = + n3b_knots_array[map_3b[i][j][k]][2][m]; + + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),2) = + n3b_knots_array[map_3b[i][j][k]][2][4] - n3b_knots_array[map_3b[i][j][k]][2][3]; + + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),1) = + n3b_knots_array[map_3b[i][j][k]][1][4] - n3b_knots_array[map_3b[i][j][k]][1][3]; + + d_n3b_knot_matrix_spacings_view(map3b_view(i, j, k),0) = + n3b_knots_array[map_3b[i][j][k]][0][4] - n3b_knots_array[map_3b[i][j][k]][0][3]; + } + Kokkos::deep_copy(d_n3b_knot_matrix, d_n3b_knot_matrix_view); + Kokkos::deep_copy(d_n3b_knot_matrix_spacings, d_n3b_knot_matrix_spacings_view); + + // Set knots spacings + + Kokkos::realloc(d_n3b_knot_spacings, interaction_count, 3); + auto d_n3b_knot_spacings_view = Kokkos::create_mirror(d_n3b_knot_spacings); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + d_n3b_knot_spacings_view(map3b_view(i, j, k), 0) = + 1 / (n3b_knots_array[map_3b[i][j][k]][0][5] - n3b_knots_array[map_3b[i][j][k]][0][4]); + + d_n3b_knot_spacings_view(map3b_view(i, j, k), 1) = + 1 / (n3b_knots_array[map_3b[i][j][k]][1][5] - n3b_knots_array[map_3b[i][j][k]][1][4]); + + d_n3b_knot_spacings_view(map3b_view(i, j, k), 2) = + 1 / (n3b_knots_array[map_3b[i][j][k]][2][5] - n3b_knots_array[map_3b[i][j][k]][2][4]); + } + } + } + Kokkos::deep_copy(d_n3b_knot_spacings, d_n3b_knot_spacings_view); + + // Copy coefficients + + Kokkos::realloc(d_coefficients_3b, interaction_count, max_knots - 4, max_knots - 4, + max_knots - 4); + auto d_coefficients_3b_view = Kokkos::create_mirror(d_coefficients_3b); + + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + for (int i = 0; i < n3b_coeff_array_size[map_3b[n][m][o]][0]; i++) { + for (int j = 0; j < n3b_coeff_array_size[map_3b[n][m][o]][1]; j++) { + for (int k = 0; k < n3b_coeff_array_size[map_3b[n][m][o]][2]; k++) { + d_coefficients_3b_view(map3b_view(n, m, o), i, j, k) = + n3b_coeff_array[map_3b[n][m][o]][i][j][k]; + } + } + } + } + } + } + Kokkos::deep_copy(d_coefficients_3b, d_coefficients_3b_view); + // + // Create derivative coefficients + + // TODO: Shrink size + Kokkos::realloc(d_dncoefficients_3b, interaction_count, 3, max_knots - 4, max_knots - 4, + max_knots - 4); + auto d_dncoefficients_3b_view = Kokkos::create_mirror(d_dncoefficients_3b); + + //Notice the order for d_dncoefficients_3b_view(map3b_view(n, m, o), X, i, j, k) + //d_dncoefficients_3b_view(map3b_view(n, m, o), 2, i, j, k) --> coeff for rjk + //d_dncoefficients_3b_view(map3b_view(n, m, o), 1, i, j, k) --> coeff for rik + //d_dncoefficients_3b_view(map3b_view(n, m, o), 0, i, j, k) --> coeff for rij + // + //This is because- + //In n3b_knot_matrix[i][j][k], + //n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + int coeff_dim1 = n3b_coeff_array_size[map_3b[n][m][o]][0]; + int coeff_dim2 = n3b_coeff_array_size[map_3b[n][m][o]][1]; + int coeff_dim3 = n3b_coeff_array_size[map_3b[n][m][o]][2]; + for (int i = 0; i < coeff_dim1; i++) { + for (int j = 0; j < coeff_dim2; j++) { + for (int k = 0; k < coeff_dim3; k++) { + F_FLOAT dntemp4 = + 3 / (n3b_knots_array[map_3b[n][m][o]][0][k + 4] - n3b_knots_array[map_3b[n][m][o]][0][k + 1]); + + d_dncoefficients_3b_view(map3b_view(n, m, o), 2, i, j, k) = + (n3b_coeff_array[map_3b[n][m][o]][i][j][k + 1] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + } + } + } + + for (int i = 0; i < coeff_dim1; i++) { + std::vector> dncoeff_vect2; + for (int j = 0; j < coeff_dim2; j++) { + F_FLOAT dntemp4 = + 3 / (n3b_knots_array[map_3b[n][m][o]][1][j + 4] - n3b_knots_array[map_3b[n][m][o]][1][j + 1]); + + std::vector dncoeff_vect; + for (int k = 0; k < coeff_dim3; k++) { + d_dncoefficients_3b_view(map3b_view(n, m, o), 1, i, j, k) = + (n3b_coeff_array[map_3b[n][m][o]][i][j + 1][k] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + } + } + } + + for (int i = 0; i < coeff_dim1; i++) { + F_FLOAT dntemp4 = + 3 / (n3b_knots_array[map_3b[n][m][o]][2][i + 4] - n3b_knots_array[map_3b[n][m][o]][2][i + 1]); + for (int j = 0; j < coeff_dim2; j++) { + for (int k = 0; k < coeff_dim3; k++) { + d_dncoefficients_3b_view(map3b_view(n, m, o), 0, i, j, k) = + (n3b_coeff_array[map_3b[n][m][o]][i + 1][j][k] - n3b_coeff_array[map_3b[n][m][o]][i][j][k]) * dntemp4; + } + } + } + } + } + } + Kokkos::deep_copy(d_dncoefficients_3b, d_dncoefficients_3b_view); + + // Set spline constants + + Kokkos::realloc(constants_3b, interaction_count, 3, max_knots - 4); + auto constants_3b_view = Kokkos::create_mirror(constants_3b); + + //In n3b_knot_matrix[i][j][k], + //n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][2] - 4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][2][l], 1); + for (int k = 0; k < 16; k++) + constants_3b_view(map3b_view(n, m, o), 0, l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][1] - 4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][1][l], 1); + for (int k = 0; k < 16; k++) + constants_3b_view(map3b_view(n, m, o), 1, l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 0; l < n3b_knots_array_size[map_3b[n][m][o]][0] -4; l++) { + auto c = get_constants(&n3b_knots_array[map_3b[n][m][o]][0][l], 1); + for (int k = 0; k < 16; k++) + constants_3b_view(map3b_view(n, m, o), 2, l, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + } + } + } + Kokkos::deep_copy(constants_3b, constants_3b_view); + + Kokkos::realloc(dnconstants_3b, interaction_count, 3, max_knots - 6); + auto dnconstants_3b_view = Kokkos::create_mirror(dnconstants_3b); + + for (int n = 1; n < num_of_elements + 1; n++) { + for (int m = 1; m < num_of_elements + 1; m++) { + for (int o = 1; o < num_of_elements + 1; o++) { + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][2] - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][2][l], 1); + for (int k = 0; k < 9; k++) + dnconstants_3b_view(map3b_view(n, m, o), 0, l - 1, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][1] - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][1][l], 1); + for (int k = 0; k < 9; k++) + dnconstants_3b_view(map3b_view(n, m, o), 1, l - 1, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + for (int l = 1; l < n3b_knots_array_size[map_3b[n][m][o]][0] - 5; l++) { + auto c = get_dnconstants(&n3b_knots_array[map_3b[n][m][o]][0][l], 1); + for (int k = 0; k < 9; k++) + dnconstants_3b_view(map3b_view(n, m, o), 2, l - 1, k) = + (std::isinf(c[k]) || std::isnan(c[k])) ? 0 : c[k]; + } + } + } + } + Kokkos::deep_copy(dnconstants_3b, dnconstants_3b_view); +} + +template +template +KOKKOS_INLINE_FUNCTION void PairUF3Kokkos::twobody(const int itype, const int jtype, + const F_FLOAT r, F_FLOAT &evdwl, + F_FLOAT &fpair) const +{ + + // Find knot starting position + int interaction_id = map2b(itype, jtype); + int start_index = 3; + while (r > d_n2b_knot(interaction_id, start_index + 1)) start_index++; + //int start_index = 3+(int)((r-d_n2b_knot(interaction_id,0))/d_n2b_knot_spacings(interaction_id)); + + F_FLOAT r_values[4]; + r_values[0] = 1; + r_values[1] = r; + r_values[2] = r_values[1] * r_values[1]; + + if (EVFLAG) { + r_values[3] = r_values[2] * r_values[1]; + // Calculate energy + evdwl = constants_2b(interaction_id, start_index, 0); + evdwl += r_values[1] * constants_2b(interaction_id, start_index, 1); + evdwl += r_values[2] * constants_2b(interaction_id, start_index, 2); + evdwl += r_values[3] * constants_2b(interaction_id, start_index, 3); + evdwl += constants_2b(interaction_id, start_index - 1, 4); + evdwl += r_values[1] * constants_2b(interaction_id, start_index - 1, 5); + evdwl += r_values[2] * constants_2b(interaction_id, start_index - 1, 6); + evdwl += r_values[3] * constants_2b(interaction_id, start_index - 1, 7); + evdwl += constants_2b(interaction_id, start_index - 2, 8); + evdwl += r_values[1] * constants_2b(interaction_id, start_index - 2, 9); + evdwl += r_values[2] * constants_2b(interaction_id, start_index - 2, 10); + evdwl += r_values[3] * constants_2b(interaction_id, start_index - 2, 11); + evdwl += constants_2b(interaction_id, start_index - 3, 12); + evdwl += r_values[1] * constants_2b(interaction_id, start_index - 3, 13); + evdwl += r_values[2] * constants_2b(interaction_id, start_index - 3, 14); + evdwl += r_values[3] * constants_2b(interaction_id, start_index - 3, 15); + } + + // Calculate force + fpair = dnconstants_2b(interaction_id, start_index - 1, 0); + fpair += r_values[1] * dnconstants_2b(interaction_id, start_index - 1, 1); + fpair += r_values[2] * dnconstants_2b(interaction_id, start_index - 1, 2); + fpair += dnconstants_2b(interaction_id, start_index - 2, 3); + fpair += r_values[1] * dnconstants_2b(interaction_id, start_index - 2, 4); + fpair += r_values[2] * dnconstants_2b(interaction_id, start_index - 2, 5); + fpair += dnconstants_2b(interaction_id, start_index - 3, 6); + fpair += r_values[1] * dnconstants_2b(interaction_id, start_index - 3, 7); + fpair += r_values[2] * dnconstants_2b(interaction_id, start_index - 3, 8); +} + +template +template +KOKKOS_INLINE_FUNCTION void PairUF3Kokkos::threebody( + const int itype, const int jtype, const int ktype, const F_FLOAT value_rij, + const F_FLOAT value_rik, const F_FLOAT value_rjk, F_FLOAT &evdwl, F_FLOAT (&fforce)[3]) const +{ + evdwl = 0; + fforce[0] = 0; + fforce[1] = 0; + fforce[2] = 0; + + F_FLOAT evals[3][4]; + F_FLOAT dnevals[3][4]; + int start_indices[3]; + F_FLOAT r[3] = {value_rij, value_rik, value_rjk}; + int interaction_id = map3b(itype, jtype, ktype); + + auto coefficients = + Kokkos::subview(d_coefficients_3b, interaction_id, Kokkos::ALL, Kokkos::ALL, Kokkos::ALL); + auto dncoefficients = Kokkos::subview(d_dncoefficients_3b, interaction_id, Kokkos::ALL, + Kokkos::ALL, Kokkos::ALL, Kokkos::ALL); + //Notice the 2-d in d_n3b_knot_matrix + // + //In d_n3b_knot_matrix[i][j][k], + //d_n3b_knot_matrix[i][j][k][0] is the knot_vector along jk, + //d_n3b_knot_matrix[i][j][k][1] is the knot_vector along ik, + //d_n3b_knot_matrix[i][j][k][2] is the knot_vector along ij, + // + //and r[0] = rij, r[1] = rik and r[2] = rjk + //see n3b_knot_matrix and pair_uf3.cpp for more details + for (int d = 0; d < 3; d++) { + start_indices[d] = 3; + while (r[d] > d_n3b_knot_matrix(interaction_id, 2-d, start_indices[d] + 1)) start_indices[d]++; + //start_indices[d] = 3+(int)((r[d]-d_n3b_knot_matrix(interaction_id, 2-d, 0))/d_n3b_knot_matrix_spacings(interaction_id, 2-d)); + + F_FLOAT r_values[4]; + r_values[0] = 1; + r_values[1] = r[d]; + r_values[2] = r_values[1] * r_values[1]; + + r_values[3] = r_values[2] * r_values[1]; + + // Calculate energy + evals[d][0] = constants_3b(interaction_id, d, start_indices[d], 0); + evals[d][0] += r_values[1] * constants_3b(interaction_id, d, start_indices[d], 1); + evals[d][0] += r_values[2] * constants_3b(interaction_id, d, start_indices[d], 2); + evals[d][0] += r_values[3] * constants_3b(interaction_id, d, start_indices[d], 3); + evals[d][1] = constants_3b(interaction_id, d, start_indices[d] - 1, 4); + evals[d][1] += r_values[1] * constants_3b(interaction_id, d, start_indices[d] - 1, 5); + evals[d][1] += r_values[2] * constants_3b(interaction_id, d, start_indices[d] - 1, 6); + evals[d][1] += r_values[3] * constants_3b(interaction_id, d, start_indices[d] - 1, 7); + evals[d][2] = constants_3b(interaction_id, d, start_indices[d] - 2, 8); + evals[d][2] += r_values[1] * constants_3b(interaction_id, d, start_indices[d] - 2, 9); + evals[d][2] += r_values[2] * constants_3b(interaction_id, d, start_indices[d] - 2, 10); + evals[d][2] += r_values[3] * constants_3b(interaction_id, d, start_indices[d] - 2, 11); + evals[d][3] = constants_3b(interaction_id, d, start_indices[d] - 3, 12); + evals[d][3] += r_values[1] * constants_3b(interaction_id, d, start_indices[d] - 3, 13); + evals[d][3] += r_values[2] * constants_3b(interaction_id, d, start_indices[d] - 3, 14); + evals[d][3] += r_values[3] * constants_3b(interaction_id, d, start_indices[d] - 3, 15); + + dnevals[d][0] = dnconstants_3b(interaction_id, d, start_indices[d] - 1, 0); + dnevals[d][0] += r_values[1] * dnconstants_3b(interaction_id, d, start_indices[d] - 1, 1); + dnevals[d][0] += r_values[2] * dnconstants_3b(interaction_id, d, start_indices[d] - 1, 2); + dnevals[d][1] = dnconstants_3b(interaction_id, d, start_indices[d] - 2, 3); + dnevals[d][1] += r_values[1] * dnconstants_3b(interaction_id, d, start_indices[d] - 2, 4); + dnevals[d][1] += r_values[2] * dnconstants_3b(interaction_id, d, start_indices[d] - 2, 5); + dnevals[d][2] = dnconstants_3b(interaction_id, d, start_indices[d] - 3, 6); + dnevals[d][2] += r_values[1] * dnconstants_3b(interaction_id, d, start_indices[d] - 3, 7); + dnevals[d][2] += r_values[2] * dnconstants_3b(interaction_id, d, start_indices[d] - 3, 8); + dnevals[d][3] = 0; + } + + if (EVFLAG) { + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 4; k++) { + evdwl += coefficients(start_indices[0] - i, start_indices[1] - j, start_indices[2] - k) * + evals[0][i] * evals[1][j] * evals[2][k]; + } + } + } + } + + for (int i = 0; i < 3; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 4; k++) { + fforce[0] += dncoefficients(0, start_indices[0] - 3 + i, start_indices[1] - 3 + j, + start_indices[2] - 3 + k) * + dnevals[0][2 - i] * evals[1][3 - j] * evals[2][3 - k]; + } + } + } + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 3; j++) { + for (int k = 0; k < 4; k++) { + fforce[1] += dncoefficients(1, start_indices[0] - 3 + i, start_indices[1] - 3 + j, + start_indices[2] - 3 + k) * + evals[0][3 - i] * dnevals[1][2 - j] * evals[2][3 - k]; + } + } + } + + for (int i = 0; i < 4; i++) { + for (int j = 0; j < 4; j++) { + for (int k = 0; k < 3; k++) { + fforce[2] += dncoefficients(2, start_indices[0] - 3 + i, start_indices[1] - 3 + j, + start_indices[2] - 3 + k) * + evals[0][3 - i] * evals[1][3 - j] * dnevals[2][2 - k]; + } + } + } +} + +template void PairUF3Kokkos::compute(int eflag_in, int vflag_in) +{ + eflag = eflag_in; + vflag = vflag_in; + + if (neighflag == FULL) no_virial_fdotr_compute = 1; + + ev_init(eflag, vflag, 0); + + // reallocate per-atom arrays if necessary + + if (eflag_atom) { + memoryKK->destroy_kokkos(k_eatom, eatom); + memoryKK->create_kokkos(k_eatom, eatom, maxeatom, "pair:eatom"); + d_eatom = k_eatom.view(); + } + if (vflag_atom) { + memoryKK->destroy_kokkos(k_vatom, vatom); + memoryKK->create_kokkos(k_vatom, vatom, maxvatom, "pair:vatom"); + d_vatom = k_vatom.view(); + } + + atomKK->sync(execution_space, datamask_read); + if (eflag || vflag) atomKK->modified(execution_space,datamask_modify); + else atomKK->modified(execution_space,F_MASK); + + x = atomKK->k_x.template view(); + f = atomKK->k_f.template view(); + tag = atomKK->k_tag.template view(); + type = atomKK->k_type.template view(); + nlocal = atom->nlocal; + newton_pair = force->newton_pair; + nall = atom->nlocal + atom->nghost; + k_cutsq.template sync(); //Sync the device memory of k_cutsq with + //the array from the host memory; this updates d_cutsq also + k_cut_3b.template sync(); + k_min_cut_3b.template sync(); + + inum = list->inum; + const int ignum = inum + list->gnum; + NeighListKokkos *k_list = static_cast *>(list); + d_ilist = k_list->d_ilist; + d_numneigh = k_list->d_numneigh; + d_neighbors = k_list->d_neighbors; + + copymode = 1; + + escatter = ScatterEType(d_eatom); + fscatter = ScatterFType(f); + vscatter = ScatterVType(d_vatom); + //cvscatter = ScatterCVType(d_cvatom); + + EV_FLOAT ev; + EV_FLOAT ev_all; + + // build short neighbor list + + int max_neighs = d_neighbors.extent(1); + + if (((int)d_neighbors_short.extent(1) != max_neighs) || + ((int)d_neighbors_short.extent(0) != ignum)) { + d_neighbors_short = Kokkos::View("UF3::neighbors_short", ignum, max_neighs); + } + if (d_numneigh_short.extent(0) != ignum) + d_numneigh_short = Kokkos::View("UF3::numneighs_short", ignum); + Kokkos::parallel_for( + Kokkos::RangePolicy(0, ignum), *this); + + // loop over neighbor list of my atoms + + if (evflag) { + Kokkos::parallel_reduce( + Kokkos::RangePolicy>(0, inum), *this, ev); + } + else{ + Kokkos::parallel_for( + Kokkos::RangePolicy>(0, inum), *this); + } + ev_all += ev; + + Kokkos::Experimental::contribute(d_eatom, escatter); + Kokkos::Experimental::contribute(d_vatom, vscatter); + //Kokkos::Experimental::contribute(d_cvatom, cvscatter); + Kokkos::Experimental::contribute(f, fscatter); + + if (eflag_global) eng_vdwl += ev_all.evdwl; + if (vflag_global) { + virial[0] += ev_all.v[0]; + virial[1] += ev_all.v[1]; + virial[2] += ev_all.v[2]; + virial[3] += ev_all.v[3]; + virial[4] += ev_all.v[4]; + virial[5] += ev_all.v[5]; + } + + if (eflag_atom) { + k_eatom.template modify(); + k_eatom.template sync(); + } + + if (vflag_atom) { + k_vatom.template modify(); + k_vatom.template sync(); + } + + if (cvflag_atom) { + //k_cvatom.template modify(); + //k_cvatom.template sync(); + } + + if (vflag_fdotr) pair_virial_fdotr_compute(this); + + copymode = 0; +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION void PairUF3Kokkos::operator()(TagPairUF3ComputeShortNeigh, + 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 jnum = d_numneigh[i]; + int inside = 0; + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors(i, jj); + j &= NEIGHMASK; + + const X_FLOAT delx = xtmp - x(j, 0); + const X_FLOAT dely = ytmp - x(j, 1); + const X_FLOAT delz = ztmp - x(j, 2); + const F_FLOAT rsq = delx * delx + dely * dely + delz * delz; + + const int itype = type[i]; + const int jtype = type[j]; + + if (rsq <= d_cutsq(itype, jtype)) { + d_neighbors_short(i, inside) = j; + inside++; + } + } + d_numneigh_short(i) = inside; +} + +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::operator()(TagPairUF3ComputeFullA, const int &ii, + EV_FLOAT &ev) const +{ + // The f array is duplicated for OpenMP, atomic for CUDA, and neither for Serial + + auto v_f = vscatter.access(); + auto a_f = fscatter.access(); + auto a_cvatom = cvscatter.access(); + + F_FLOAT del_rji[3], del_rki[3], del_rkj[3], triangle_eval[3]; + F_FLOAT fij[3], fik[3], fjk[3]; + F_FLOAT fji[3], fki[3], fkj[3]; + F_FLOAT Fj[3], Fk[3]; + F_FLOAT evdwl = 0, evdwl3 = 0; + F_FLOAT fpair = 0; + + const int i = d_ilist[ii]; + const int itype = type[i]; + const X_FLOAT xtmp = x(i, 0); + const X_FLOAT ytmp = x(i, 1); + const X_FLOAT ztmp = x(i, 2); + + // two-body interactions + + const int jnum = d_numneigh_short[i]; + + F_FLOAT fxtmpi = 0.0; + F_FLOAT fytmpi = 0.0; + F_FLOAT fztmpi = 0.0; + + for (int jj = 0; jj < jnum; jj++) { + int j = d_neighbors_short(i, jj); + j &= NEIGHMASK; + const int jtype = type[j]; + + const X_FLOAT delx = xtmp - x(j, 0); + const X_FLOAT dely = ytmp - x(j, 1); + const X_FLOAT delz = ztmp - x(j, 2); + const F_FLOAT rsq = delx * delx + dely * dely + delz * delz; + + if (rsq >= d_cutsq(itype, jtype)) continue; + + const F_FLOAT rij = sqrt(rsq); + this->template twobody(itype, jtype, rij, evdwl, fpair); + + fpair = -fpair / rij; + + fxtmpi += delx * fpair; + fytmpi += dely * fpair; + fztmpi += delz * fpair; + a_f(j, 0) -= delx * fpair; + a_f(j, 1) -= dely * fpair; + a_f(j, 2) -= delz * fpair; + + if (EVFLAG) { + if (eflag) ev.evdwl += evdwl; + if (vflag_either || eflag_atom) + this->template ev_tally(ev, i, j, evdwl, fpair, delx, dely, delz); + } + } + + // 3-body interaction + // jth atom + const int jnumm1 = jnum - 1; + for (int jj = 0; jj < jnumm1; jj++) { + int j = d_neighbors_short(i, jj); + j &= NEIGHMASK; + const int jtype = type[j]; + del_rji[0] = x(j, 0) - xtmp; + del_rji[1] = x(j, 1) - ytmp; + del_rji[2] = x(j, 2) - ztmp; + F_FLOAT rij = sqrt(del_rji[0] * del_rji[0] + del_rji[1] * del_rji[1] + del_rji[2] * del_rji[2]); + + F_FLOAT fxtmpj = 0.0; + F_FLOAT fytmpj = 0.0; + F_FLOAT fztmpj = 0.0; + + for (int kk = jj + 1; kk < jnum; kk++) { + int k = d_neighbors_short(i, kk); + k &= NEIGHMASK; + const int ktype = type[k]; + + // Notice the order of d_min_cut_3b[i][j][k] + //In d_min_cut_3b[i][j][k], + //d_min_cut_3b[i][j][k][0] is the knot_vector along jk, + //d_min_cut_3b[i][j][k][1] is the knot_vector along ik, + //d_min_cut_3b[i][j][k][2] is the knot_vector along ij, + //see pair_uf3.cpp for more details + if (rij < d_min_cut_3b(itype, jtype, ktype, 2)) continue; + if (rij > d_cut_3b(itype, jtype, ktype)) continue; + + del_rki[0] = x(k, 0) - xtmp; + del_rki[1] = x(k, 1) - ytmp; + del_rki[2] = x(k, 2) - ztmp; + F_FLOAT rik = + sqrt(del_rki[0] * del_rki[0] + del_rki[1] * del_rki[1] + del_rki[2] * del_rki[2]); + + if (rik < d_min_cut_3b(itype, jtype, ktype, 1)) continue; + if (rik > d_cut_3b(itype, ktype, jtype)) continue; + + del_rkj[0] = x(k, 0) - x(j, 0); + del_rkj[1] = x(k, 1) - x(j, 1); + del_rkj[2] = x(k, 2) - x(j, 2); + F_FLOAT rjk = + sqrt(del_rkj[0] * del_rkj[0] + del_rkj[1] * del_rkj[1] + del_rkj[2] * del_rkj[2]); + if (rjk < d_min_cut_3b(itype, jtype, ktype, 0)) continue; + this->template threebody(itype, jtype, ktype, rij, rik, rjk, evdwl3, triangle_eval); + + fij[0] = *(triangle_eval + 0) * (del_rji[0] / rij); + fji[0] = -fij[0]; + fik[0] = *(triangle_eval + 1) * (del_rki[0] / rik); + fki[0] = -fik[0]; + fjk[0] = *(triangle_eval + 2) * (del_rkj[0] / rjk); + fkj[0] = -fjk[0]; + + fij[1] = *(triangle_eval + 0) * (del_rji[1] / rij); + fji[1] = -fij[1]; + fik[1] = *(triangle_eval + 1) * (del_rki[1] / rik); + fki[1] = -fik[1]; + fjk[1] = *(triangle_eval + 2) * (del_rkj[1] / rjk); + fkj[1] = -fjk[1]; + + fij[2] = *(triangle_eval + 0) * (del_rji[2] / rij); + fji[2] = -fij[2]; + fik[2] = *(triangle_eval + 1) * (del_rki[2] / rik); + fki[2] = -fik[2]; + fjk[2] = *(triangle_eval + 2) * (del_rkj[2] / rjk); + fkj[2] = -fjk[2]; + + Fj[0] = fji[0] + fjk[0]; + Fj[1] = fji[1] + fjk[1]; + Fj[2] = fji[2] + fjk[2]; + + Fk[0] = fki[0] + fkj[0]; + Fk[1] = fki[1] + fkj[1]; + Fk[2] = fki[2] + fkj[2]; + + fxtmpi += (fij[0] + fik[0]); + fytmpi += (fij[1] + fik[1]); + fztmpi += (fij[2] + fik[2]); + fxtmpj += Fj[0]; + fytmpj += Fj[1]; + fztmpj += Fj[2]; + a_f(k, 0) += Fk[0]; + a_f(k, 1) += Fk[1]; + a_f(k, 2) += Fk[2]; + + if (EVFLAG) { + if (eflag) { ev.evdwl += evdwl3; } + if (vflag_either || eflag_atom) { + this->template ev_tally3(ev, i, j, k, evdwl3, 0.0, Fj, Fk, del_rji, del_rki); + if (cvflag_atom) { + + F_FLOAT ric[3]; + ric[0] = THIRD * (-del_rji[0] - del_rki[0]); + ric[1] = THIRD * (-del_rji[1] - del_rki[1]); + ric[2] = THIRD * (-del_rji[2] - del_rki[2]); + a_cvatom(i, 0) += ric[0] * (-Fj[0] - Fk[0]); + a_cvatom(i, 1) += ric[1] * (-Fj[1] - Fk[1]); + a_cvatom(i, 2) += ric[2] * (-Fj[2] - Fk[2]); + a_cvatom(i, 3) += ric[0] * (-Fj[1] - Fk[1]); + a_cvatom(i, 4) += ric[0] * (-Fj[2] - Fk[2]); + a_cvatom(i, 5) += ric[1] * (-Fj[2] - Fk[2]); + a_cvatom(i, 6) += ric[1] * (-Fj[0] - Fk[0]); + a_cvatom(i, 7) += ric[2] * (-Fj[0] - Fk[0]); + a_cvatom(i, 8) += ric[2] * (-Fj[1] - Fk[1]); + + double rjc[3]; + rjc[0] = THIRD * (del_rji[0] - del_rkj[0]); + rjc[1] = THIRD * (del_rji[1] - del_rkj[1]); + rjc[2] = THIRD * (del_rji[2] - del_rkj[2]); + + a_cvatom(j, 0) += rjc[0] * Fj[0]; + a_cvatom(j, 1) += rjc[1] * Fj[1]; + a_cvatom(j, 2) += rjc[2] * Fj[2]; + a_cvatom(j, 3) += rjc[0] * Fj[1]; + a_cvatom(j, 4) += rjc[0] * Fj[2]; + a_cvatom(j, 5) += rjc[1] * Fj[2]; + a_cvatom(j, 6) += rjc[1] * Fj[0]; + a_cvatom(j, 7) += rjc[2] * Fj[0]; + a_cvatom(j, 8) += rjc[2] * Fj[1]; + + double rkc[3]; + rkc[0] = THIRD * (del_rki[0] + del_rkj[0]); + rkc[1] = THIRD * (del_rki[1] + del_rkj[1]); + rkc[2] = THIRD * (del_rki[2] + del_rkj[2]); + + a_cvatom(k, 0) += rkc[0] * Fk[0]; + a_cvatom(k, 1) += rkc[1] * Fk[1]; + a_cvatom(k, 2) += rkc[2] * Fk[2]; + a_cvatom(k, 3) += rkc[0] * Fk[1]; + a_cvatom(k, 4) += rkc[0] * Fk[2]; + a_cvatom(k, 5) += rkc[1] * Fk[2]; + a_cvatom(k, 6) += rkc[1] * Fk[0]; + a_cvatom(k, 7) += rkc[2] * Fk[0]; + a_cvatom(k, 8) += rkc[2] * Fk[1]; + } + } + } + } + a_f(j, 0) += fxtmpj; + a_f(j, 1) += fytmpj; + a_f(j, 2) += fztmpj; + } + + a_f(i, 0) += fxtmpi; + a_f(i, 1) += fytmpi; + a_f(i, 2) += fztmpi; +} + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::operator()(TagPairUF3ComputeFullA, + const int &ii) const +{ + EV_FLOAT ev; + this->template operator()(TagPairUF3ComputeFullA(), ii, ev); +} + +/* ---------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &epair, + const F_FLOAT &fpair, const F_FLOAT &delx, const F_FLOAT &dely, + const F_FLOAT &delz) const +{ + + // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, + // and neither for Serial + + auto a_eatom = escatter.access(); + auto a_vatom = vscatter.access(); + auto a_cvatom = cvscatter.access(); + + if (eflag_atom) { + const E_FLOAT epairhalf = 0.5 * epair; + a_eatom[i] += epairhalf; + a_eatom[j] += epairhalf; + } + + if (vflag_either) { + const E_FLOAT v0 = delx * delx * fpair; + const E_FLOAT v1 = dely * dely * fpair; + const E_FLOAT v2 = delz * delz * fpair; + const E_FLOAT v3 = delx * dely * fpair; + const E_FLOAT v4 = delx * delz * fpair; + const E_FLOAT v5 = dely * delz * fpair; + + if (vflag_global) { + ev.v[0] += v0; + ev.v[1] += v1; + ev.v[2] += v2; + ev.v[3] += v3; + ev.v[4] += v4; + ev.v[5] += v5; + } + + if (vflag_atom) { + a_vatom(i, 0) += 0.5 * v0; + a_vatom(i, 1) += 0.5 * v1; + a_vatom(i, 2) += 0.5 * v2; + a_vatom(i, 3) += 0.5 * v3; + a_vatom(i, 4) += 0.5 * v4; + a_vatom(i, 5) += 0.5 * v5; + + a_vatom(j, 0) += 0.5 * v0; + a_vatom(j, 1) += 0.5 * v1; + a_vatom(j, 2) += 0.5 * v2; + a_vatom(j, 3) += 0.5 * v3; + a_vatom(j, 4) += 0.5 * v4; + a_vatom(j, 5) += 0.5 * v5; + } + + if (cvflag_atom) { + a_cvatom(i, 0) += 0.5 * v0; + a_cvatom(i, 1) += 0.5 * v1; + a_cvatom(i, 2) += 0.5 * v2; + a_cvatom(i, 3) += 0.5 * v3; + a_cvatom(i, 4) += 0.5 * v4; + a_cvatom(i, 5) += 0.5 * v5; + a_cvatom(i, 6) += 0.5 * v3; + a_cvatom(i, 7) += 0.5 * v4; + a_cvatom(i, 8) += 0.5 * v5; + a_cvatom(j, 0) += 0.5 * v0; + a_cvatom(j, 1) += 0.5 * v1; + a_cvatom(j, 2) += 0.5 * v2; + a_cvatom(j, 3) += 0.5 * v3; + a_cvatom(j, 4) += 0.5 * v4; + a_cvatom(j, 5) += 0.5 * v5; + a_cvatom(j, 6) += 0.5 * v3; + a_cvatom(j, 7) += 0.5 * v4; + a_cvatom(j, 8) += 0.5 * v5; + } + } +} + +/* ---------------------------------------------------------------------- + tally eng_vdwl and virial into global and per-atom accumulators + called by SW and hbond potentials, newton_pair is always on + virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk + ------------------------------------------------------------------------- */ + +template +template +KOKKOS_INLINE_FUNCTION void +PairUF3Kokkos::ev_tally3(EV_FLOAT &ev, const int &i, const int &j, int &k, + const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, + F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const +{ + F_FLOAT epairthird, v[6]; + + // The eatom and vatom arrays are duplicated for OpenMP, atomic for CUDA, + // and neither for Serial + + auto a_eatom = escatter.access(); + auto a_vatom = vscatter.access(); + + if (eflag_atom) { + epairthird = THIRD * (evdwl + ecoul); + a_eatom[i] += epairthird; + a_eatom[j] += epairthird; + a_eatom[k] += epairthird; + } + + if (vflag_either) { + v[0] = drji[0] * fj[0] + drki[0] * fk[0]; + v[1] = drji[1] * fj[1] + drki[1] * fk[1]; + v[2] = drji[2] * fj[2] + drki[2] * fk[2]; + v[3] = drji[0] * fj[1] + drki[0] * fk[1]; + v[4] = drji[0] * fj[2] + drki[0] * fk[2]; + v[5] = drji[1] * fj[2] + drki[1] * fk[2]; + + if (vflag_global) { + ev.v[0] += v[0]; + ev.v[1] += v[1]; + ev.v[2] += v[2]; + ev.v[3] += v[3]; + ev.v[4] += v[4]; + ev.v[5] += v[5]; + } + + if (vflag_atom) { + a_vatom(i, 0) += THIRD * v[0]; + a_vatom(i, 1) += THIRD * v[1]; + a_vatom(i, 2) += THIRD * v[2]; + a_vatom(i, 3) += THIRD * v[3]; + a_vatom(i, 4) += THIRD * v[4]; + a_vatom(i, 5) += THIRD * v[5]; + + a_vatom(j, 0) += THIRD * v[0]; + a_vatom(j, 1) += THIRD * v[1]; + a_vatom(j, 2) += THIRD * v[2]; + a_vatom(j, 3) += THIRD * v[3]; + a_vatom(j, 4) += THIRD * v[4]; + a_vatom(j, 5) += THIRD * v[5]; + + a_vatom(k, 0) += THIRD * v[0]; + a_vatom(k, 1) += THIRD * v[1]; + a_vatom(k, 2) += THIRD * v[2]; + a_vatom(k, 3) += THIRD * v[3]; + a_vatom(k, 4) += THIRD * v[4]; + a_vatom(k, 5) += THIRD * v[5]; + } + } +} + +/* ---------------------------------------------------------------------- + tally eng_vdwl and virial into global and per-atom accumulators + called by SW and hbond potentials, newton_pair is always on + virial = riFi + rjFj + rkFk = (rj-ri) Fj + (rk-ri) Fk = drji*fj + drki*fk + ------------------------------------------------------------------------- */ + +template +template +void PairUF3Kokkos::copy_2d(V &d, T **h, int m, int n) +{ + Kokkos::View tmp("pair::tmp", m, n); //Create tmp view(array) on + //device memory + + //auto h_view = Kokkos::create_mirror_view(tmp); + auto h_view = Kokkos::create_mirror(tmp); //Create a mirror of the device + //view(array) tmp, as deep_copy is only possible for mirror views + + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + h_view(i, j) = h[i][j]; //fill mirror + } + //views with data from normal array 'h' which always lives on host memory + } + + Kokkos::deep_copy(tmp, h_view); //Deepcopy data from h_view(host) to tmp(device) + + d = tmp; +} + +template +template +void PairUF3Kokkos::copy_3d(V &d, T ***h, int m, int n, int o) +{ + Kokkos::View tmp("pair::tmp", m, n, o); //Create tmp view(array) on + //device memory + + //auto h_view = Kokkos::create_mirror_view(tmp); //create_mirror always copies + //the data. create_mirror_view only copies data if the host cannot access the + //data + auto h_view = Kokkos::create_mirror(tmp); //Create a mirror of the device + //view(array) tmp, as deep_copy is only possible for mirror views + for (int i = 0; i < m; i++) { + for (int j = 0; j < n; j++) { + for (int k = 0; k < o; k++) { h_view(i, j, k) = h[i][j][k]; } //fill mirror + //views with data from normal array 'h' which always lives on host memory + } + } + + Kokkos::deep_copy(tmp, h_view); //Deepcopy data from h_view(host) to tmp(device) + + d = tmp; +} + +template +std::vector PairUF3Kokkos::get_constants(double *knots, double coefficient) +{ + + std::vector constants(16); + + constants[0] = coefficient * + (-cube(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[1] = coefficient * + (3 * square(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[2] = coefficient * + (-3 * knots[0] / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[3] = coefficient * + (1 / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + constants[4] = coefficient * + (square(knots[1]) * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + square(knots[0]) * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] * knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[5] = coefficient * + (-square(knots[1]) / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 2 * knots[1] * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + square(knots[0]) / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 2 * knots[0] * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + knots[0] * knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[0] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[6] = coefficient * + (2 * knots[1] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + 2 * knots[0] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[7] = coefficient * + (-1 / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 1 / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 1 / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + constants[8] = coefficient * + (-knots[0] * square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] * knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] * square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[9] = coefficient * + (2 * knots[0] * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + knots[1] * knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[1] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 2 * knots[2] * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) + + square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[10] = coefficient * + (-knots[0] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + 2 * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) - + 2 * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[11] = coefficient * + (1 / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + 1 / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 1 / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + constants[12] = coefficient * + (cube(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + constants[13] = coefficient * + (-3 * square(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + constants[14] = coefficient * + (3 * knots[4] / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + constants[15] = coefficient * + (-1 / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + + return constants; +} + +template +std::vector PairUF3Kokkos::get_dnconstants(double *knots, double coefficient) +{ + std::vector constants(9); + + constants[0] = coefficient * + (square(knots[0]) / + (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + constants[1] = coefficient * + (-2 * knots[0] / + (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + constants[2] = coefficient * + (1 / (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + constants[3] = coefficient * + (-knots[1] * knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + knots[0] * knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + constants[4] = coefficient * + (knots[1] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[0] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2])) + + knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + constants[5] = coefficient * + (-1 / (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + 1 / (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + constants[6] = coefficient * + (square(knots[3]) / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + constants[7] = coefficient * + (-2 * knots[3] / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + constants[8] = coefficient * + (1 / (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + + return constants; +} + +template +double PairUF3Kokkos::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq, + double /*factor_coul*/, double factor_lj, double &fforce) +{ + double value = 0.0; + double r = sqrt(rsq); + int interaction_id = map2b(itype, jtype); + int start_index = 3; + while (r > d_n2b_knot(interaction_id, start_index + 1)) start_index++; + + if (r < d_cutsq(itype, jtype)) { + F_FLOAT r_values[4]; + r_values[0] = 1; + r_values[1] = r; + r_values[2] = r_values[1] * r_values[1]; + r_values[3] = r_values[2] * r_values[1]; + + // Calculate energy + value = constants_2b(interaction_id, start_index, 0); + value += r_values[1] * constants_2b(interaction_id, start_index, 1); + value += r_values[2] * constants_2b(interaction_id, start_index, 2); + value += r_values[3] * constants_2b(interaction_id, start_index, 3); + value += constants_2b(interaction_id, start_index - 1, 4); + value += r_values[1] * constants_2b(interaction_id, start_index - 1, 5); + value += r_values[2] * constants_2b(interaction_id, start_index - 1, 6); + value += r_values[3] * constants_2b(interaction_id, start_index - 1, 7); + value += constants_2b(interaction_id, start_index - 2, 8); + value += r_values[1] * constants_2b(interaction_id, start_index - 2, 9); + value += r_values[2] * constants_2b(interaction_id, start_index - 2, 10); + value += r_values[3] * constants_2b(interaction_id, start_index - 2, 11); + value += constants_2b(interaction_id, start_index - 3, 12); + value += r_values[1] * constants_2b(interaction_id, start_index - 3, 13); + value += r_values[2] * constants_2b(interaction_id, start_index - 3, 14); + value += r_values[3] * constants_2b(interaction_id, start_index - 3, 15); + + // Calculate force + fforce = dnconstants_2b(interaction_id, start_index - 1, 0); + fforce += r_values[1] * dnconstants_2b(interaction_id, start_index - 1, 1); + fforce += r_values[2] * dnconstants_2b(interaction_id, start_index - 1, 2); + fforce += dnconstants_2b(interaction_id, start_index - 2, 3); + fforce += r_values[1] * dnconstants_2b(interaction_id, start_index - 2, 4); + fforce += r_values[2] * dnconstants_2b(interaction_id, start_index - 2, 5); + fforce += dnconstants_2b(interaction_id, start_index - 3, 6); + fforce += r_values[1] * dnconstants_2b(interaction_id, start_index - 3, 7); + fforce += r_values[2] * dnconstants_2b(interaction_id, start_index - 3, 8); + } + + return factor_lj * value; +} + +namespace LAMMPS_NS { +template class PairUF3Kokkos; +#ifdef KOKKOS_ENABLE_CUDA +template class PairUF3Kokkos; +#endif +} // namespace LAMMPS_NS diff --git a/src/KOKKOS/pair_uf3_kokkos.h b/src/KOKKOS/pair_uf3_kokkos.h new file mode 100644 index 0000000000..15c2832da1 --- /dev/null +++ b/src/KOKKOS/pair_uf3_kokkos.h @@ -0,0 +1,187 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(uf3/kk,PairUF3Kokkos) +PairStyle(uf3/kk/device,PairUF3Kokkos) +// clang-format on +#else + +#ifndef LMP_PAIR_UF3_KOKKOS_H +#define LMP_PAIR_UF3_KOKKOS_H + +#include "kokkos.h" +#include "pair_kokkos.h" +#include "pair_uf3.h" + +template struct TagPairUF3ComputeFullA {}; +struct TagPairUF3ComputeShortNeigh {}; + +namespace LAMMPS_NS { + +template class PairUF3Kokkos : public PairUF3 { + public: + PairUF3Kokkos(class LAMMPS *); + ~PairUF3Kokkos() override; + void compute(int, int) override; + void settings(int, char **) override; + void coeff(int, char **) override; + void allocate(); + void init_style() override; + void init_list(int, class NeighList *) override; // needed for ptr to full neigh list + double init_one(int, int) override; // needed for cutoff radius for neighbour list + double single(int, int, int, int, double, double, double, double &) override; + + template void copy_2d(V &d, T **h, int m, int n); + template void copy_3d(V &d, T ***h, int m, int n, int o); + + template + KOKKOS_INLINE_FUNCTION void operator()(TagPairUF3ComputeFullA, const int &, + EV_FLOAT &) const; + + template + KOKKOS_INLINE_FUNCTION void operator()(TagPairUF3ComputeFullA, + const int &) const; + + KOKKOS_INLINE_FUNCTION + void operator()(TagPairUF3ComputeShortNeigh, const int &) const; + + enum { EnabledNeighFlags = FULL }; + enum { COUL_FLAG = 0 }; + typedef DeviceType device_type; + typedef ArrayTypes AT; + typedef EV_FLOAT value_type; + + protected: + typename AT::tdual_ffloat_2d k_cutsq;//Create a DualView, defination of tdual_ffloat_2d in kokkos_type.h + typename AT::t_ffloat_2d d_cutsq; //t_ffloat_2d = t_dev ==> Creates a new View d_cutsq + //the type of d_cutsq is decided by the Device(not host) type for the DualView k_cutsq + //Meaning the memory location of d_cutsq is the same as the Device(not host) memory location of + //k_cutsq + typedef Kokkos::DualView tdual_ffloat_3d; + typedef Kokkos::DualView tdual_ffloat_4d; + tdual_ffloat_3d k_cut_3b; + tdual_ffloat_4d k_min_cut_3b; + typename tdual_ffloat_3d::t_dev d_cut_3b; + typename tdual_ffloat_4d::t_dev d_min_cut_3b; + template void destroy_3d(TYPE data, typename TYPE::value_type*** &array); + template void destroy_4d(TYPE data, typename TYPE::value_type**** &array); + Kokkos::View /*d_cutsq,*/ d_cut_3b_list; + //Kokkos::View d_cut_3b; + + Kokkos::View d_coefficients_2b; + Kokkos::View d_dncoefficients_2b; + Kokkos::View d_n2b_knot; + Kokkos::View d_n2b_knot_spacings; + Kokkos::View map2b; + Kokkos::View constants; + Kokkos::View dnconstants; + Kokkos::View d_n3b_knot_matrix; + Kokkos::View d_coefficients_3b; + Kokkos::View d_dncoefficients_3b; + Kokkos::View d_n3b_knot_spacings; + Kokkos::View d_n3b_knot_matrix_spacings; + Kokkos::View map3b; + + Kokkos::View constants_2b; + Kokkos::View dnconstants_2b; + Kokkos::View constants_3b; + Kokkos::View dnconstants_3b; + + std::vector get_constants(double *knots, double coefficient); + std::vector get_dnconstants(double *knots, double coefficient); + + int coefficients_created = 0; + void create_coefficients(); + void create_3b_coefficients(); + void create_2b_coefficients(); + std::vector get_coefficients(const double *knots, const double coefficient) const; + std::vector get_dncoefficients(const double *knots, const double coefficient) const; + + template + void twobody(const int itype, const int jtype, const F_FLOAT r, F_FLOAT &evdwl, + F_FLOAT &fpair) const; + template + void threebody(const int itype, const int jtype, const int ktype, const F_FLOAT value_rij, + const F_FLOAT value_rik, const F_FLOAT value_rjk, F_FLOAT &evdwl3, + F_FLOAT (&fforce)[3]) const; + + template + KOKKOS_INLINE_FUNCTION void + ev_tally(EV_FLOAT &ev, const int &i, const int &j, const F_FLOAT &epair, const F_FLOAT &fpair, + const F_FLOAT &delx, const F_FLOAT &dely, const F_FLOAT &delz) const; + + template + KOKKOS_INLINE_FUNCTION void ev_tally3(EV_FLOAT &ev, const int &i, const int &j, int &k, + const F_FLOAT &evdwl, const F_FLOAT &ecoul, F_FLOAT *fj, + F_FLOAT *fk, F_FLOAT *drji, F_FLOAT *drki) const; + + typename AT::t_x_array_randomread x; + typename AT::t_f_array f; + typename AT::t_tagint_1d tag; + typename AT::t_int_1d_randomread type; + + DAT::tdual_efloat_1d k_eatom; + DAT::tdual_virial_array k_vatom; + typename AT::t_efloat_1d d_eatom; + typename AT::t_virial_array d_vatom; + + using ScatterFType = Kokkos::Experimental::ScatterView; + ScatterFType fscatter; + using ScatterVType = Kokkos::Experimental::ScatterView; + ScatterVType vscatter; + using ScatterCVType = Kokkos::Experimental::ScatterView; + ScatterCVType cvscatter; + using ScatterEType = Kokkos::Experimental::ScatterView; + ScatterEType escatter; + + typename AT::t_neighbors_2d d_neighbors; + typename AT::t_int_1d_randomread d_ilist; + typename AT::t_int_1d_randomread d_numneigh; + + int neighflag, newton_pair; + int nlocal, nall, eflag, vflag; + + int inum; + Kokkos::View d_neighbors_short; + Kokkos::View d_numneigh_short; + + friend void pair_virial_fdotr_compute(PairUF3Kokkos *); +}; + +KOKKOS_INLINE_FUNCTION int min(int i, int j) +{ + return i < j ? i : j; +} +KOKKOS_INLINE_FUNCTION int max(int i, int j) +{ + return i > j ? i : j; +} + +} // namespace LAMMPS_NS + +#endif +#endif + diff --git a/src/ML-UF3/pair_uf3.cpp b/src/ML-UF3/pair_uf3.cpp new file mode 100644 index 0000000000..1f41ddd336 --- /dev/null +++ b/src/ML-UF3/pair_uf3.cpp @@ -0,0 +1,1984 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#include "pair_uf3.h" + +#include "uf3_bspline_basis2.h" +#include "uf3_bspline_basis3.h" + +#include "atom.h" +#include "comm.h" +#include "error.h" +#include "force.h" +#include "math_const.h" +#include "memory.h" +#include "neigh_list.h" +#include "neighbor.h" +#include "text_file_reader.h" + +#include +#include + +using namespace LAMMPS_NS; +using MathConst::THIRD; + +/* ---------------------------------------------------------------------- */ + +PairUF3::PairUF3(LAMMPS *lmp) : + Pair(lmp), setflag_3b(nullptr), knot_spacing_type_2b(nullptr), knot_spacing_type_3b(nullptr), + cut(nullptr), cut_3b(nullptr), cut_3b_list(nullptr), min_cut_3b(nullptr), + knot_spacing_2b(nullptr), knot_spacing_3b(nullptr), n2b_knots_array(nullptr), + n2b_coeff_array(nullptr), n2b_knots_array_size(nullptr), + n2b_coeff_array_size(nullptr), cached_constants_2b(nullptr), + cached_constants_2b_deri(nullptr), map_3b(nullptr), n3b_knots_array(nullptr), + n3b_coeff_array(nullptr), n3b_knots_array_size(nullptr), + n3b_coeff_array_size(nullptr), coeff_for_der_jk(nullptr), + coeff_for_der_ik(nullptr), coeff_for_der_ij(nullptr), + cached_constants_3b(nullptr), cached_constants_3b_deri(nullptr), + neighshort(nullptr) +{ + single_enable = 1; // 1 if single() routine exists + one_coeff = 1; // 1 if allows only one coeff * * call + restartinfo = 0; // 1 if pair style writes restart info + maxshort = 20; + centroidstressflag = CENTROID_AVAIL; + manybody_flag = 1; + bsplines_created = 0; +} + +/* ---------------------------------------------------------------------- */ + +PairUF3::~PairUF3() +{ + if (copymode) return; + if (allocated) { + memory->destroy(setflag); + memory->destroy(cutsq); + memory->destroy(cut); + memory->destroy(knot_spacing_type_2b); + memory->destroy(knot_spacing_2b); + memory->destroy(n2b_knots_array_size); + memory->destroy(n2b_coeff_array_size); + memory->destroy(n2b_knots_array); + memory->destroy(n2b_coeff_array); + memory->destroy(cached_constants_2b); + memory->destroy(cached_constants_2b_deri); + + if (pot_3b) { + memory->destroy(setflag_3b); + memory->destroy(cut_3b); + memory->destroy(cut_3b_list); + memory->destroy(min_cut_3b); + memory->destroy(neighshort); + memory->destroy(knot_spacing_type_3b); + memory->destroy(knot_spacing_3b); + memory->destroy(map_3b); + memory->destroy(n3b_knots_array_size); + memory->destroy(n3b_coeff_array_size); + memory->destroy(n3b_knots_array); + memory->destroy(n3b_coeff_array); + memory->destroy(coeff_for_der_jk); + memory->destroy(coeff_for_der_ik); + memory->destroy(coeff_for_der_ij); + memory->destroy(cached_constants_3b); + memory->destroy(cached_constants_3b_deri); + } + } +} + +/* ---------------------------------------------------------------------- + * global settings + * ---------------------------------------------------------------------- */ + +void PairUF3::settings(int narg, char **arg) +{ + + if (narg != 1) + error->all(FLERR, + "Invalid number of arguments for pair_style uf3" + " Are you using a 2-body or 2 & 3-body UF potential?"); + nbody_flag = utils::numeric(FLERR, arg[0], true, lmp); + const int num_of_elements = atom->ntypes; + if (nbody_flag == 2) { + pot_3b = false; + manybody_flag = 0; + } else if (nbody_flag == 3) { + pot_3b = true; + single_enable = 0; + } else + error->all(FLERR, "Pair style uf3 not (yet) implemented for {}-body terms", nbody_flag); + +} + +/* ---------------------------------------------------------------------- + * set coeffs for one or more type pairs + * ---------------------------------------------------------------------- */ +void PairUF3::coeff(int narg, char **arg) +{ + if (narg != 3+atom->ntypes) + error->all(FLERR, "Invalid number of arguments uf3 in pair coeffs."); + + if (!allocated) allocate(); + + map_element2type(narg-3, arg+3, false); + + if (comm->me == 0) + uf3_read_unified_pot_file(arg[2]); + communicate(); + +} + +void PairUF3::allocate() +{ + allocated = 1; + const int num_of_elements = atom->ntypes; + + map = new int[num_of_elements+1]; //No need to delete map as ~Pair deletes map + + // Contains info about wether UF potential were found for type i and j + memory->create(setflag, num_of_elements + 1, num_of_elements + 1, "pair:setflag"); + + // Contains info about 2-body cutoff distance for type i and j + // cutsq is the global variable + // Even though we are making cutsq don't manually change the default values + // Lammps take care of setting the value + memory->create(cutsq, num_of_elements + 1, num_of_elements + 1, "pair:cutsq"); + // cut is specific to this pair style. We will set the values in cut + memory->create(cut, num_of_elements + 1, num_of_elements + 1, "pair:cut"); + //Contains info about type of knot_spacing--> 0 = uniform knot spacing (default) + //1 = non-uniform knot spacing + memory->create(knot_spacing_type_2b, num_of_elements + 1, num_of_elements + 1, + "pair:knot_spacing_type_2b"); + memory->create(knot_spacing_2b, num_of_elements + 1, num_of_elements + 1, + "pair:knot_spacing_2b"); + + //Contains size of 2b knots vectors and 2b coeff matrices + memory->create(n2b_knots_array_size, num_of_elements + 1, num_of_elements + 1, + "pair:n2b_knots_array_size"); + memory->create(n2b_coeff_array_size, num_of_elements + 1, num_of_elements + 1, + "pair:n2b_coeff_array_size"); + + if (pot_3b) { + // Contains info about wether UF potential were found for type i, j and k + memory->create(setflag_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:setflag_3b"); + // Contains info about 3-body cutoff distance for type i, j and k + memory->create(cut_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:cut_3b"); + // Contains info about 3-body cutoff distance for type i, j and k + // for constructing 3-body list + memory->create(cut_3b_list, num_of_elements + 1, num_of_elements + 1, + "pair:cut_3b_list"); + // Contains info about minimum 3-body cutoff distance for type i, j and k + memory->create(min_cut_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, 3, "pair:min_cut_3b"); + //Contains info about type of knot_spacing--> 0 = uniform knot spacing (default) + //1 = non-uniform knot spacing + memory->create(knot_spacing_type_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:knot_spacing_type_3b"); + memory->create(knot_spacing_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, 3, "pair:knot_spacing_3b"); + + tot_interaction_count_3b = 0; + //conatins map of I-J-K interaction + memory->create(map_3b, num_of_elements + 1, num_of_elements + 1, + num_of_elements + 1, "pair:map_3b"); + + // setting cut_3b, setflag = 0 and map_3b + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + cut_3b_list[i][j] = 0; + setflag[i][j] = 0; + n2b_coeff_array_size[i][j] = 0; + n2b_knots_array_size[i][j] = 0; + + for (int k = 1; k < num_of_elements + 1; k++) { + cut_3b[i][j][k] = 0; + min_cut_3b[i][j][k][0] = 0; + min_cut_3b[i][j][k][1] = 0; + min_cut_3b[i][j][k][2] = 0; + + setflag_3b[i][j][k] = 0; + + map_3b[i][j][k] = tot_interaction_count_3b; + tot_interaction_count_3b++; + } + } + } + + //contains sizes of 3b knots vectors and 3b coeff matrices + memory->create(n3b_knots_array_size, tot_interaction_count_3b, 3, + "pair:n3b_knots_array_size"); + memory->create(n3b_coeff_array_size, tot_interaction_count_3b, 3, + "pair:n3b_coeff_array_size"); + for (int i = 0; i < tot_interaction_count_3b; i++) { + n3b_coeff_array_size[i][0] = 0; + n3b_coeff_array_size[i][1] = 0; + n3b_coeff_array_size[i][2] = 0; + + n3b_knots_array_size[i][0] = 0; + n3b_knots_array_size[i][1] = 0; + n3b_knots_array_size[i][2] = 0; + } + + memory->create(neighshort, maxshort, "pair:neighshort"); + + } +} + +void PairUF3::uf3_read_unified_pot_file(char *potf_name) +{ + //Go through the entire file and get the sizes of knot vectors and + //coeff vectors/matrices + // + //Create arrays + // + //Go through the file again and read the knots and coefficients + // + + const int num_of_elements = atom->ntypes; + + //if (true) { + FILE *fp = utils::open_potential(potf_name, lmp, nullptr); + if (!fp) + error->all(FLERR, + "Cannot open UF3 potential file {}: {}", + potf_name, utils::getsyserror()); + + TextFileReader txtfilereader(fp, "UF3:POTFP"); + txtfilereader.ignore_comments = false; + + //while loop over the entire file, find blocks starting with #UF3 POT + //if block found read the very next line to determine 2B or 3B block + //if 2B read the knot vector and coeff vector size + //if 3B read the knot vectors and coeff matrix size + int line_counter = 1; + char *line; + while((line = txtfilereader.next_line(1))){ + Tokenizer line_token(line); + + //Detect start of a block + if (line_token.contains("#UF3 POT")) { + //Block start detected + if (line_token.contains("UNITS:") == 0) + error->all(FLERR, + "UF3: {} file does not contain the 'UNITS:' metadata in " + "the header", + potf_name); + + //Read the 2nd line of the block + std::string temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp2nd_line(temp_line); + + std::string nbody_on_file = fp2nd_line.next_string(); + if (nbody_on_file == "2B") { + //2B block + if (fp2nd_line.count() != 6) + error->all(FLERR, "UF3: Expected 6 words on line {} of {} file " + "but found {} word/s", + line_counter, potf_name, fp2nd_line.count()); + + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + for (int i=1; iall(FLERR, + "UF3: Current implementation is throughly tested only " + "for leading_trim=0"); + if (trailing_trim != 3) + error->all(FLERR, + "UF3: Current implementation is throughly tested only " + "for trailing_trim=3"); + + //read next line, should contain cutoff and size of knot vector + temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp3rd_line(temp_line); + if (fp3rd_line.count() != 2) + error->all(FLERR, + "UF3: Expected only 2 words on 3rd line => " + "Rij_CUTOFF NUM_OF_KNOTS. Found {} word/s", + fp3rd_line.count()); + + //cut is used in init_one which is called by pair.cpp at line 267 + //where the return of init_one is squared + cut[itype][jtype] = fp3rd_line.next_double(); + cut[jtype][itype] = cut[itype][jtype]; + + int num_knots_2b = fp3rd_line.next_int(); + n2b_knots_array_size[itype][jtype] = num_knots_2b; + n2b_knots_array_size[jtype][itype] = num_knots_2b; + max_num_knots_2b = std::max(max_num_knots_2b, num_knots_2b); + + //skip next line + txtfilereader.skip_line(); + line_counter++; + + //read number of coeff + temp_line = txtfilereader.next_line(1); + line_counter++; + ValueTokenizer fp5th_line(temp_line); + + int num_coeff_2b = fp5th_line.next_int(); + if (num_coeff_2b <= 0) + error->all(FLERR, + "UF3: 0 or negative number found for num_coeff_2b" + " on line {} of the potential file",line_counter); + n2b_coeff_array_size[itype][jtype] = num_coeff_2b; + n2b_coeff_array_size[jtype][itype] = num_coeff_2b; + max_num_coeff_2b = std::max(max_num_coeff_2b, num_coeff_2b); + } + } + else if ((nbody_on_file == "3B") && (pot_3b)) { + //3B block + if (fp2nd_line.count() != 7) + error->all(FLERR, "UF3: Expected 7 words on line {} of {} file" + "but found {} word/s", + line_counter, potf_name, fp2nd_line.count()); + + if (nbody_on_file == "3B") { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + std::string element3 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + int ktype = 0; + for (int i=1; iall(FLERR, + "UF3: Current implementation is throughly tested " + "only for leading_trim=0"); + if (trailing_trim != 3) + error->all(FLERR, + "UF3: Current implementation is throughly tested " + "only for trailing_trim=3"); + + //read next line, should contain cutoffs and size of knot vectors + temp_line = txtfilereader.next_line(6); + line_counter++; + ValueTokenizer fp3rd_line(temp_line); + + if (fp3rd_line.count() != 6) + error->all(FLERR, + "UF3: Expected only 6 numbers on 3rd line => " + "Rjk_CUTOFF Rik_CUTOFF Rij_CUTOFF NUM_OF_KNOTS_JK " + "NUM_OF_KNOTS_IK NUM_OF_KNOTS_IJ Found {} number/s", + fp3rd_line.count()); + + double cut3b_rjk = fp3rd_line.next_double(); + double cut3b_rij = fp3rd_line.next_double(); + double cut3b_rik = fp3rd_line.next_double(); + + if (cut3b_rij != cut3b_rik) + error->all(FLERR, + "UF3: rij!=rik for {}-{}-{}. " + "Current implementation only works for rij=rik", + element1, element2, element3); + + if (2 * cut3b_rik != cut3b_rjk) + error->all(FLERR, + "UF3: 2rij=2rik!=rik for {}-{}-{}. " + "Current implementation only works for 2rij=2rik!=rik", + element1, element2, element3); + + cut_3b_list[itype][jtype] = + std::max(cut3b_rij, cut_3b_list[itype][jtype]); + cut_3b_list[itype][ktype] = + std::max(cut_3b_list[itype][ktype], cut3b_rik); + + cut_3b[itype][jtype][ktype] = cut3b_rij; + cut_3b[itype][ktype][jtype] = cut3b_rik; + + int num_knots_3b_jk = fp3rd_line.next_int(); + int num_knots_3b_ik = fp3rd_line.next_int(); + int num_knots_3b_ij = fp3rd_line.next_int(); + + n3b_knots_array_size[map_3b[itype][jtype][ktype]][0] = num_knots_3b_jk; + n3b_knots_array_size[map_3b[itype][jtype][ktype]][1] = num_knots_3b_ik; + n3b_knots_array_size[map_3b[itype][jtype][ktype]][2] = num_knots_3b_ij; + + n3b_knots_array_size[map_3b[itype][ktype][jtype]][0] = num_knots_3b_jk; + n3b_knots_array_size[map_3b[itype][ktype][jtype]][1] = num_knots_3b_ij; + n3b_knots_array_size[map_3b[itype][ktype][jtype]][2] = num_knots_3b_ik; + + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_jk); + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_ik); + max_num_knots_3b = std::max(max_num_knots_3b, num_knots_3b_ij); + + //skip next 3 line + txtfilereader.skip_line(); + line_counter++; + txtfilereader.skip_line(); + line_counter++; + txtfilereader.skip_line(); + line_counter++; + + //read number of coeff + temp_line = txtfilereader.next_line(3); + line_counter++; + ValueTokenizer fp7th_line(temp_line); + + if (fp7th_line.count() != 3) + error->all(FLERR, + "UF3: Expected 3 numbers on 7th line => " + "SHAPE_OF_COEFF_MATRIX[I][J][K] " + "found {} numbers", + fp7th_line.count()); + + int coeff_matrix_dim1 = fp7th_line.next_int(); + int coeff_matrix_dim2 = fp7th_line.next_int(); + int coeff_matrix_dim3 = fp7th_line.next_int(); + + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][0] = coeff_matrix_dim1; + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][1] = coeff_matrix_dim2; + n3b_coeff_array_size[map_3b[itype][jtype][ktype]][2] = coeff_matrix_dim3; + + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][0] = coeff_matrix_dim2; + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][1] = coeff_matrix_dim1; + n3b_coeff_array_size[map_3b[itype][ktype][jtype]][2] = coeff_matrix_dim3; + + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim1); + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim2); + max_num_coeff_3b = std::max(max_num_coeff_3b,coeff_matrix_dim3); + } + } + } + else { + if (!((nbody_on_file == "3B") && (!pot_3b))) + error->all(FLERR, + "UF3: Expected either '2B' or '3B' word on line {} of {} file", + line_counter, potf_name); + } + } //if of #UF3 POT + line_counter++; + } // while + + //Create knot and coeff arrays + if (max_num_knots_2b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 2B knot vector\n" + "Possibly no 2B UF3 potential block detected in {} file", + potf_name); + memory->destroy(n2b_knots_array); + memory->create(n2b_knots_array, num_of_elements + 1, num_of_elements + 1, + max_num_knots_2b, "pair:n2b_knots_array"); + + if (max_num_coeff_2b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 2B coeff vector\n" + "Possibly no 2B UF3 potential block detected in {} file", + potf_name); + + memory->destroy(n2b_coeff_array); + memory->create(n2b_coeff_array, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, "pair:n2b_coeff_array"); + + + if (pot_3b) { + if (max_num_knots_3b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 3B knot vector\n" + "Possibly no 3B UF3 potential block detected in {} file", + potf_name); + memory->destroy(n3b_knots_array); + memory->create(n3b_knots_array, tot_interaction_count_3b, 3, + max_num_knots_3b, "pair:n3b_knots_array"); + + if (max_num_coeff_3b <= 0) + error->all(FLERR, + "UF3: Error reading the size of 3B coeff matrices\n" + "Possibly no 3B UF3 potential block detected in {} file", + potf_name); + memory->destroy(n3b_coeff_array); + memory->create(n3b_coeff_array, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:n3b_coeff_array"); + } + + //Go back to the begning of the file + txtfilereader.rewind(); + + //Go through the file again and fill knot and coeff arrays + //while loop to read the data + while((line = txtfilereader.next_line(1))){ + Tokenizer line_token(line); + + //Detect start of a block + if (line_token.contains("#UF3 POT")) { + //Block start detected + //Read the 2nd line of the block + std::string temp_line = txtfilereader.next_line(1); + ValueTokenizer fp2nd_line(temp_line); + std::string nbody_on_file = fp2nd_line.next_string(); + + if (nbody_on_file == "2B") { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + for (int i=1; iall(FLERR, + "UF3: Expected either 'uk'(uniform-knots) or 'nk'(non-uniform knots). " + "Found {} on the 2nd line of {}-{} interaction block", + knot_type, element1, element2); + + if ((itype != 0) && (jtype != 0)) { + //skip line containing info of cutoff and knot vect size + txtfilereader.skip_line(); + + int num_knots_2b = n2b_knots_array_size[itype][jtype]; + + temp_line = txtfilereader.next_line(num_knots_2b); + ValueTokenizer fp4th_line(temp_line); + + if (fp4th_line.count() != num_knots_2b) + error->all(FLERR, "UF3: Error readig the 2B potential block for {}-{}\n" + "Expecter {} numbers on 4th line of the block but found {} " + "numbers", num_knots_2b,fp4th_line.count()); + + for (int k = 0; k < num_knots_2b; k++) { + n2b_knots_array[itype][jtype][k] = fp4th_line.next_double(); + n2b_knots_array[jtype][itype][k] = n2b_knots_array[itype][jtype][k]; + } + + knot_spacing_2b[itype][jtype] = n2b_knots_array[itype][jtype][4] - + n2b_knots_array[itype][jtype][3]; + knot_spacing_2b[jtype][itype] = knot_spacing_2b[itype][jtype]; + + //skip next line + txtfilereader.skip_line(); + + int num_of_coeff_2b = n2b_coeff_array_size[itype][jtype]; + + temp_line = txtfilereader.next_line(num_of_coeff_2b); + ValueTokenizer fp6th_line(temp_line); + + if (fp6th_line.count() != num_of_coeff_2b) + error->all(FLERR, + "UF3: Error readig the 2B potential block for {}-{}\n" + "Expecter {} numbers on 6th line of the block but found {} " + "numbers", num_knots_2b,fp4th_line.count()); + + for (int k = 0; k < num_of_coeff_2b; k++) { + n2b_coeff_array[itype][jtype][k] = fp6th_line.next_double(); + n2b_coeff_array[jtype][itype][k] = n2b_coeff_array[itype][jtype][k]; + } + + if (num_knots_2b != num_of_coeff_2b + 4) + error->all(FLERR, + "UF3: {}-{} interaction block has incorrect knot and " + "coeff data nknots!=ncoeffs + 3 + 1", + element1, element2); + + setflag[itype][jtype] = 1; + setflag[jtype][itype] = 1; + } + } + + if ((nbody_on_file == "3B") && (pot_3b)) { + //get the elements + std::string element1 = fp2nd_line.next_string(); + std::string element2 = fp2nd_line.next_string(); + std::string element3 = fp2nd_line.next_string(); + int itype = 0; + int jtype = 0; + int ktype = 0; + for (int i=1; iall(FLERR, + "UF3: Expected either 'uk'(uniform-knots) or 'nk'(non-uniform knots) " + "Found {} on the 2nd line of {}-{}-{} interaction block", + knot_type, element1, element2, element3); + + if ((itype != 0) && (jtype != 0) && (ktype!=0)) { + //skip line containing info of cutoffs and knot vector sizes + txtfilereader.skip_line(); + + int num_knots_3b_jk = n3b_knots_array_size[map_3b[itype][jtype][ktype]][0]; + int num_knots_3b_ik = n3b_knots_array_size[map_3b[itype][jtype][ktype]][1]; + int num_knots_3b_ij = n3b_knots_array_size[map_3b[itype][jtype][ktype]][2]; + + temp_line = txtfilereader.next_line(num_knots_3b_jk); + ValueTokenizer fp4th_line(temp_line); + if (fp4th_line.count() != num_knots_3b_jk) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 4th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_jk, fp4th_line.count()); + + for (int i = 0; i < num_knots_3b_jk; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][0][i] = + fp4th_line.next_double(); + n3b_knots_array[map_3b[itype][ktype][jtype]][0][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][i]; + } + + min_cut_3b[itype][jtype][ktype][0] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][0]; + min_cut_3b[itype][ktype][jtype][0] = + n3b_knots_array[map_3b[itype][ktype][jtype]][0][0]; + + knot_spacing_3b[itype][jtype][ktype][0] = + n3b_knots_array[map_3b[itype][jtype][ktype]][0][4] - + n3b_knots_array[map_3b[itype][jtype][ktype]][0][3]; + knot_spacing_3b[itype][ktype][jtype][0] = + knot_spacing_3b[itype][jtype][ktype][0]; + + temp_line = txtfilereader.next_line(num_knots_3b_ik); + ValueTokenizer fp5th_line(temp_line); + if (fp5th_line.count() != num_knots_3b_ik) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 5th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_ik, fp5th_line.count()); + + for (int i = 0; i < num_knots_3b_ik; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][1][i] = + fp5th_line.next_double(); + n3b_knots_array[map_3b[itype][ktype][jtype]][2][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][i]; + } + + min_cut_3b[itype][jtype][ktype][1] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][0]; + min_cut_3b[itype][ktype][jtype][2] = + n3b_knots_array[map_3b[itype][ktype][jtype]][2][0]; + + knot_spacing_3b[itype][jtype][ktype][1] = + n3b_knots_array[map_3b[itype][jtype][ktype]][1][4] - + n3b_knots_array[map_3b[itype][jtype][ktype]][1][3]; + knot_spacing_3b[itype][ktype][jtype][2] = + knot_spacing_3b[itype][jtype][ktype][1]; + + temp_line = txtfilereader.next_line(num_knots_3b_ij); + ValueTokenizer fp6th_line(temp_line); + if (fp6th_line.count() != num_knots_3b_ij) + error->all(FLERR, + "UF3: Error readig the 3B potential block for {}-{}-{}\n" + "Expected {} numbers on 6th line of the block but found {} " + "numbers", element1, element2, element3, + num_knots_3b_ij, fp6th_line.count()); + + for (int i = 0; i < num_knots_3b_ij; i++) { + n3b_knots_array[map_3b[itype][jtype][ktype]][2][i] = + fp6th_line.next_double(); + n3b_knots_array[map_3b[itype][ktype][jtype]][1][i] = + n3b_knots_array[map_3b[itype][jtype][ktype]][2][i]; + } + + min_cut_3b[itype][jtype][ktype][2] = + n3b_knots_array[map_3b[itype][jtype][ktype]][2][0]; + min_cut_3b[itype][ktype][jtype][1] = + n3b_knots_array[map_3b[itype][ktype][jtype]][1][0]; + + knot_spacing_3b[itype][jtype][ktype][2] = + n3b_knots_array[map_3b[itype][jtype][ktype]][2][4] - + n3b_knots_array[map_3b[itype][jtype][ktype]][2][3]; + knot_spacing_3b[itype][ktype][jtype][1] = + knot_spacing_3b[itype][jtype][ktype][2]; + + //skip next line + txtfilereader.skip_line(); + + int coeff_matrix_dim1 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][0]; + int coeff_matrix_dim2 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][1]; + int coeff_matrix_dim3 = n3b_coeff_array_size[map_3b[itype][jtype][ktype]][2]; + + if (num_knots_3b_jk != coeff_matrix_dim3 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_JK) and coeff (coeff_matrix_dim3) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + if (num_knots_3b_ik != coeff_matrix_dim2 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_IK) and coeff (coeff_matrix_dim2) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + if (num_knots_3b_ij != coeff_matrix_dim1 + 3 + 1) + error->all(FLERR, + "UF3: {}-{}-{} interaction block has incorrect knot " + "(NUM_OF_KNOTS_IJ) and coeff (coeff_matrix_dim1) data " + "nknots!=ncoeffs + 3 + 1", + element1, element2, element3); + + int coeff_matrix_elements_len = coeff_matrix_dim3; + int key1 = map_3b[itype][jtype][ktype]; + int key2 = map_3b[itype][ktype][jtype]; + + int line_count = 0; + for (int i = 0; i < coeff_matrix_dim1; i++) { + for (int j = 0; j < coeff_matrix_dim2; j++) { + temp_line = txtfilereader.next_line(coeff_matrix_elements_len); + ValueTokenizer coeff_line(temp_line); + if (coeff_line.count() != coeff_matrix_elements_len) + error->all(FLERR, + "UF3: Error reading 3B potential block for {}-{}-{}\n" + "Expected {} numbers on {}th line of the block but found {} " + "numbers", element1, element2, element3, + coeff_matrix_elements_len, line_count + 8, + coeff_line.count()); + + for (int k = 0; k < coeff_matrix_dim3; k++) { + n3b_coeff_array[key1][i][j][k] = coeff_line.next_double(); + } + line_count += 1; + } + } + + for (int i = 0; i < coeff_matrix_dim1; i++) { + for (int j = 0; j < coeff_matrix_dim2; j++) { + for (int k = 0; k < coeff_matrix_dim3; k++) { + n3b_coeff_array[key2][j][i][k] = n3b_coeff_array[key1][i][j][k]; + } + } + } + + setflag_3b[itype][jtype][ktype] = 1; + setflag_3b[itype][ktype][jtype] = 1; + } + } + } // if #UF3 POT + } //while + fclose(fp); + + //Set interaction of atom types of the same elements + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + if (setflag[i][j] != 1){ + //i-j interaction not set + + //maybe i-j is mapped to some other atom type interaction? + int i_mapped_to = map[i]+1; //+1 as map starts from 0 + int j_mapped_to = map[j]+1; //+1 as map starts from 0 + + if ((i_mapped_to == i) && (j_mapped_to == j)) + //i-j is not mapped to some other atom type ie interaction is missing on file + error->all(FLERR, + "UF3: Potential for interaction {}-{} ie {}-{} not found " + "in {} file", + i, j, elements[i_mapped_to-1], elements[j_mapped_to-1], + potf_name); + + cut[i][j] = cut[i_mapped_to][j_mapped_to]; + + n2b_knots_array_size[i][j] = n2b_knots_array_size[i_mapped_to][j_mapped_to]; + n2b_coeff_array_size[i][j] = n2b_coeff_array_size[i_mapped_to][j_mapped_to]; + + knot_spacing_type_2b[i][j] = knot_spacing_type_2b[i_mapped_to][j_mapped_to]; + knot_spacing_2b[i][j] = knot_spacing_2b[i_mapped_to][j_mapped_to]; + + for (int knot_no = 0; knot_no < max_num_knots_2b; knot_no++) + n2b_knots_array[i][j][knot_no] = + n2b_knots_array[i_mapped_to][j_mapped_to][knot_no]; + + for (int coeff_no = 0; coeff_no < max_num_coeff_2b; coeff_no++) + n2b_coeff_array[i][j][coeff_no] = + n2b_coeff_array[i_mapped_to][j_mapped_to][coeff_no]; + + setflag[i][j] = 1; + } + } + } + + if (pot_3b) { + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + //for (int k = j; k < num_of_elements + 1; k++) { + for (int k = 1; k < num_of_elements + 1; k++) { + if (setflag_3b[i][j][k] != 1) { + //i-j-k interaction not set + + //maybe i-j-k is mapped to some other atom type interaction? + int i_mapped_to = map[i]+1; //+1 as map starts from 0 + int j_mapped_to = map[j]+1; //+1 as map starts from 0 + int k_mapped_to = map[k]+1; //+1 as map starts from 0 + + if ((i_mapped_to == i) && (j_mapped_to == j) && (k_mapped_to == k)) + error->all(FLERR, + "UF3: Potential for interaction {}-{}-{} ie {}-{}-{} " + " not found in {} file", + i, j, k, elements[i_mapped_to-1], elements[j_mapped_to-1], + elements[k_mapped_to-1], potf_name); + if (setflag_3b[i_mapped_to][j_mapped_to][k_mapped_to] != 1) + error->all(FLERR, + "UF3: Interaction {}-{}-{} was mapped to {}-{}-{}, but " + "potential interaction for {}-{}-{} was not found in " + "{} file", + i, j, k, i_mapped_to, j_mapped_to, k_mapped_to, + i_mapped_to, j_mapped_to, k_mapped_to, potf_name); + + + cut_3b_list[i][j] = std::max(cut_3b_list[i_mapped_to][j_mapped_to], + cut_3b_list[i][j]); + + + cut_3b[i][j][k] = cut_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + + knot_spacing_type_3b[i][j][k] = + knot_spacing_type_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + knot_spacing_3b[i][j][k][0] = + knot_spacing_3b[i_mapped_to][j_mapped_to][k_mapped_to][0]; + knot_spacing_3b[i][j][k][1] = + knot_spacing_3b[i_mapped_to][j_mapped_to][k_mapped_to][1]; + knot_spacing_3b[i][j][k][2] = + knot_spacing_3b[i_mapped_to][j_mapped_to][k_mapped_to][2]; + + int key = map_3b[i][j][k]; + int mapped_to_key = map_3b[i_mapped_to][j_mapped_to][k_mapped_to]; + + n3b_knots_array_size[key][0] = n3b_knots_array_size[mapped_to_key][0]; + n3b_knots_array_size[key][1] = n3b_knots_array_size[mapped_to_key][1]; + n3b_knots_array_size[key][2] = n3b_knots_array_size[mapped_to_key][2]; + + n3b_coeff_array_size[key][0] = n3b_coeff_array_size[mapped_to_key][0]; + n3b_coeff_array_size[key][1] = n3b_coeff_array_size[mapped_to_key][1]; + n3b_coeff_array_size[key][2] = n3b_coeff_array_size[mapped_to_key][2]; + + min_cut_3b[i][j][k][0] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][0]; + + min_cut_3b[i][j][k][1] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][1]; + + min_cut_3b[i][j][k][2] = + min_cut_3b[i_mapped_to][j_mapped_to][k_mapped_to][2]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][0]; knot_no++) + n3b_knots_array[key][0][knot_no] = n3b_knots_array[mapped_to_key][0][knot_no]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][1]; knot_no++) + n3b_knots_array[key][1][knot_no] = n3b_knots_array[mapped_to_key][1][knot_no]; + + for (int knot_no = 0; knot_no < n3b_knots_array_size[key][2]; knot_no++) + n3b_knots_array[key][2][knot_no] = n3b_knots_array[mapped_to_key][2][knot_no]; + + for (int coeff1 = 0; coeff1 < n3b_coeff_array_size[key][0]; coeff1++) + for (int coeff2 = 0; coeff2 < n3b_coeff_array_size[key][1]; coeff2++) + for (int coeff3 = 0; coeff3 < n3b_coeff_array_size[key][2]; coeff3++) + n3b_coeff_array[key][coeff1][coeff2][coeff3] = + n3b_coeff_array[mapped_to_key][coeff1][coeff2][coeff3]; + setflag_3b[i][j][k] = 1; + } + } + } + } + } +} + +//Broadcast data read from potential file to all processors +void PairUF3::communicate() +{ + const int num_of_elements = atom->ntypes; + MPI_Bcast(&cut[0][0], (num_of_elements + 1)*(num_of_elements + 1), + MPI_DOUBLE, 0, world); + + MPI_Bcast(&n2b_knots_array_size[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + MPI_Bcast(&n2b_coeff_array_size[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + MPI_Bcast(&max_num_knots_2b, 1, MPI_INT, 0, world); + MPI_Bcast(&max_num_coeff_2b, 1, MPI_INT, 0, world); + + if (pot_3b){ + MPI_Bcast(&cut_3b_list[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_DOUBLE, 0, world); + + MPI_Bcast(&cut_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_DOUBLE, 0, world); + + MPI_Bcast(&n3b_knots_array_size[0][0], tot_interaction_count_3b*3, + MPI_INT, 0, world); + MPI_Bcast(&n3b_coeff_array_size[0][0], tot_interaction_count_3b*3, + MPI_INT, 0, world); + + MPI_Bcast(&max_num_knots_3b, 1, MPI_INT, 0, world); + MPI_Bcast(&max_num_coeff_3b, 1, MPI_INT, 0, world); + } + + if (comm->me != 0) { + memory->destroy(n2b_knots_array); + memory->destroy(n2b_coeff_array); + + memory->create(n2b_knots_array, num_of_elements + 1, num_of_elements + 1, + max_num_knots_2b, "pair:n2b_knots_array"); + memory->create(n2b_coeff_array, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, "pair:n2b_coeff_array"); + if (pot_3b) { + memory->destroy(n3b_knots_array); + memory->destroy(n3b_coeff_array); + + memory->create(n3b_knots_array, tot_interaction_count_3b, 3, + max_num_knots_3b, "pair:n3b_knots_array"); + + memory->create(n3b_coeff_array, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:n3b_coeff_array"); + } + } + + MPI_Bcast(&knot_spacing_type_2b[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + MPI_Bcast(&knot_spacing_2b[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_DOUBLE, 0, world); + + MPI_Bcast(&n2b_knots_array[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*max_num_knots_2b, MPI_DOUBLE, 0, world); + MPI_Bcast(&n2b_coeff_array[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*max_num_coeff_2b, MPI_DOUBLE, 0, world); + + MPI_Bcast(&setflag[0][0], + (num_of_elements + 1)*(num_of_elements + 1), MPI_INT, 0, world); + + if (pot_3b) { + MPI_Bcast(&knot_spacing_type_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_INT, 0, world); + + MPI_Bcast(&knot_spacing_3b[0][0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1)*3, + MPI_DOUBLE, 0, world); + MPI_Bcast(&n3b_knots_array[0][0][0], + tot_interaction_count_3b*3*max_num_knots_3b, MPI_DOUBLE, 0, world); + MPI_Bcast(&n3b_coeff_array[0][0][0][0], + tot_interaction_count_3b*max_num_coeff_3b*max_num_coeff_3b*max_num_coeff_3b, + MPI_DOUBLE, 0, world); + MPI_Bcast(&setflag_3b[0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1), + MPI_INT, 0, world); + MPI_Bcast(&min_cut_3b[0][0][0][0], + (num_of_elements + 1)*(num_of_elements + 1)*(num_of_elements + 1)*3, + MPI_DOUBLE, 0, world); + } +} + +/* ---------------------------------------------------------------------- + init specific to this pair style +------------------------------------------------------------------------- */ +void PairUF3::init_style() +{ + if (force->newton_pair == 0) error->all(FLERR, "UF3: Pair style requires newton pair on"); + // request a default neighbor list + neighbor->add_request(this, NeighConst::REQ_FULL); +} + +/* ---------------------------------------------------------------------- + init list sets the pointer to full neighbour list requested in previous function +------------------------------------------------------------------------- */ + +void PairUF3::init_list(int /*id*/, class NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- + init for one type pair i,j and corresponding j,i +------------------------------------------------------------------------- */ +double PairUF3::init_one(int i /*i*/, int /*j*/ j) +{ + + if (!bsplines_created) create_bsplines(); + + //init_one is called by pair.cpp at line 267 where it is squred + //at line 268 + return cut[i][j]; +} + +void PairUF3::create_bsplines() +{ + const int num_of_elements = atom->ntypes; + bsplines_created = 1; + int spacing_type = knot_spacing_type_2b[1][1]; + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + if (setflag[i][j] != 1) + error->all(FLERR, + "UF3: Not all 2-body UF potentials are set, " + "missing potential for {}-{} interaction", + i, j); + /*if (spacing_type != knot_spacing_type_2b[i][j]) + error->all(FLERR, + "UF3: In the current version the knot spacing type, " + "for all interactions needs to be same. For {}-{} " + "i.e. {}-{} interaction expected {}, but found {}", + i,j,elements[map[i]],elements[map[j]],spacing_type, + knot_spacing_type_2b[i][j]);*/ + } + } + if (pot_3b) { + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + for (int k = 1; k < num_of_elements + 1; k++) { + if (setflag_3b[i][j][k] != 1) + error->all(FLERR, + "UF3: Not all 3-body UF potentials are set, " + "missing potential for {}-{}-{} interaction", + i, j, k); + if (spacing_type != knot_spacing_type_3b[i][j][k]) + error->all(FLERR, + "UF3: In the current version the knot spacing type, " + "for all interactions needs to be same. For {}-{}-{} " + "i.e. {}-{}-{} interaction expected{}, but found {}", + i,j,k,elements[map[i]],elements[map[j]],elements[map[k]], + spacing_type,knot_spacing_type_3b[i][j][k]); + } + } + } + } + + + if (spacing_type) { + get_starting_index_2b = &PairUF3::get_starting_index_nonuniform_2b; + if (pot_3b) + get_starting_index_3b = &PairUF3::get_starting_index_nonuniform_3b; + } + else { + get_starting_index_2b = &PairUF3::get_starting_index_uniform_2b; + if (pot_3b) + get_starting_index_3b = &PairUF3::get_starting_index_uniform_3b; + } + + create_cached_constants_2b(); + if (pot_3b) + create_cached_constants_3b(); +} + +int PairUF3::get_starting_index_uniform_2b(int i, int j, double r) +{ + return 3+(int)((r-n2b_knots_array[i][j][0])/(knot_spacing_2b[i][j])); +} + +int PairUF3::get_starting_index_uniform_3b(int i, int j, int k, double r, int knot_dim) +{ + return 3+(int)(((r-n3b_knots_array[map_3b[i][j][k]][knot_dim][0])/ + knot_spacing_3b[i][j][k][knot_dim])); +} + +int PairUF3::get_starting_index_nonuniform_2b(int i, int j, double r) +{ + for (int l = 3; l < n2b_knots_array_size[i][j]-1; ++l) { + if ((n2b_knots_array[i][j][l] <= r) && (r < n2b_knots_array[i][j][l+1])) + return l; + } + return -1; +} + +int PairUF3::get_starting_index_nonuniform_3b(int i, int j, int k, double r, int knot_dim) +{ + for (int l = 3; l < n3b_knots_array_size[map_3b[i][j][k]][knot_dim]-1; ++l) { + if ((n3b_knots_array[map_3b[i][j][k]][knot_dim][l] <= r) && + (r < n3b_knots_array[map_3b[i][j][k]][knot_dim][l+1])) + return l; + } + return -1; +} + +void PairUF3::create_cached_constants_2b() +{ + const int num_of_elements = atom->ntypes; + memory->destroy(cached_constants_2b); + memory->destroy(cached_constants_2b_deri); + memory->create(cached_constants_2b, num_of_elements + 1, num_of_elements + 1, + max_num_coeff_2b, 16, "pair:cached_constants_2b"); + + memory->create(cached_constants_2b_deri, num_of_elements + 1, + num_of_elements + 1, max_num_coeff_2b - 1, 9, + "pair:cached_constants_2b_deri"); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++ ) { + for (int l = 0; l < n2b_coeff_array_size[i][j]; l++) { + uf3_bspline_basis3 bspline_basis(lmp, &n2b_knots_array[i][j][l], + n2b_coeff_array[i][j][l]); + for (int cc = 0; cc < 16; cc++) { + cached_constants_2b[i][j][l][cc] = bspline_basis.constants[cc]; + } + } + } + } + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++) { + //initialize coeff and knots for derivative + //double* knots_for_deri = new double[n2b_knots_array_size[i][j]-2]; + double *knots_for_deri = nullptr; + memory->create(knots_for_deri, n2b_knots_array_size[i][j]-2, "pair:knots_for_deri"); + + for (int l = 1; l < n2b_knots_array_size[i][j] - 1; l++) + knots_for_deri[l-1] = n2b_knots_array[i][j][l]; + + + //double* coeff_for_deri = new double[n2b_coeff_array_size[i][j]-1]; + double *coeff_for_deri = nullptr; + memory->create(coeff_for_deri, n2b_coeff_array_size[i][j]-1, "pair:coeff_for_deri"); + for (int l = 0; l < n2b_coeff_array_size[i][j] - 1; l++) { + double dntemp = 3 / (n2b_knots_array[i][j][l + 4] - + n2b_knots_array[i][j][l + 1]); + coeff_for_deri[l] = + (n2b_coeff_array[i][j][l+1] - n2b_coeff_array[i][j][l]) * dntemp; + } + + for (int l = 0; l < n2b_coeff_array_size[i][j] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri(lmp, &knots_for_deri[l], + coeff_for_deri[l]); + for (int cc = 0; cc < 9; cc++) { + cached_constants_2b_deri[i][j][l][cc] = bspline_basis_deri.constants[cc]; + } + } + memory->destroy(knots_for_deri); + memory->destroy(coeff_for_deri); + //delete[] knots_for_deri; + //delete[] coeff_for_deri; + } + } +} + +void PairUF3::create_cached_constants_3b() +{ + const int num_of_elements = atom->ntypes; + memory->destroy(coeff_for_der_jk); + memory->destroy(coeff_for_der_ik); + memory->destroy(coeff_for_der_ij); + memory->destroy(cached_constants_3b); + memory->destroy(cached_constants_3b_deri); + + memory->create(coeff_for_der_jk, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:coeff_for_der_jk"); + + memory->create(coeff_for_der_ik, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:coeff_for_der_ik"); + + memory->create(coeff_for_der_ij, tot_interaction_count_3b, max_num_coeff_3b, + max_num_coeff_3b, max_num_coeff_3b, "pair:coeff_for_der_ij"); + + memory->create(cached_constants_3b, tot_interaction_count_3b, 3, + max_num_coeff_3b, 16, "pair:cached_constants_3b"); + + memory->create(cached_constants_3b_deri, tot_interaction_count_3b, 3, + max_num_coeff_3b - 1, 9, "pair:cached_constants_3b_deri"); + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++ ) { + for(int k = 1; k < num_of_elements + 1; k++) { + int map_to = map_3b[i][j][k]; + + for (int l = 0; l < n3b_knots_array_size[map_to][2] - 4; l++) { + uf3_bspline_basis3 bspline_basis_ij(lmp, &n3b_knots_array[map_to][2][l], 1); + for (int cc = 0; cc < 16; cc++) + cached_constants_3b[map_to][0][l][cc] = bspline_basis_ij.constants[cc]; + } + + for (int l = 0; l < n3b_knots_array_size[map_to][1] - 4; l++) { + uf3_bspline_basis3 bspline_basis_ik(lmp, &n3b_knots_array[map_to][1][l], 1); + for (int cc = 0; cc < 16; cc++) + cached_constants_3b[map_to][1][l][cc] = bspline_basis_ik.constants[cc]; + } + + for (int l = 0; l < n3b_knots_array_size[map_to][0] - 4; l++) { + uf3_bspline_basis3 bspline_basis_jk(lmp, &n3b_knots_array[map_to][0][l], 1); + for (int cc = 0; cc < 16; cc++) + cached_constants_3b[map_to][2][l][cc] = bspline_basis_jk.constants[cc]; + } + } + } + } + + for (int i = 1; i < num_of_elements + 1; i++) { + for (int j = 1; j < num_of_elements + 1; j++ ) { + for(int k = 1; k < num_of_elements + 1; k++) { + int map_to = map_3b[i][j][k]; + double **knots_for_der = nullptr;//new double*[3]; + + //n3b_knots_array_size[map_to][0] for jk knot vector --> always largest + memory->create(knots_for_der, 3, n3b_knots_array_size[map_to][0]-1, + "pair:knots_for_der"); + + //--deri_basis_jk + for (int l = 1; l < n3b_knots_array_size[map_to][0] - 1; l++) + knots_for_der[0][l-1] = n3b_knots_array[map_to][0][l]; + + for(int l = 0; l < n3b_coeff_array_size[map_to][0]; l++) { + for(int m = 0; m < n3b_coeff_array_size[map_to][1]; m++) { + for(int n = 0; n < n3b_coeff_array_size[map_to][2] - 1; n++) { + double dntemp = 3/(n3b_knots_array[map_to][0][n + 4] - + n3b_knots_array[map_to][0][n + 1]); + coeff_for_der_jk[map_to][l][m][n] = + ((n3b_coeff_array[map_to][l][m][n + 1] - + n3b_coeff_array[map_to][l][m][n])*dntemp); + } + } + } + + //--deri_basis_ik + for (int l = 1; l < n3b_knots_array_size[map_to][1] - 1; l++) + knots_for_der[1][l-1] = n3b_knots_array[map_to][1][l]; + + for (int l = 0; l < n3b_coeff_array_size[map_to][0]; l++) { + for (int m = 0; m < n3b_coeff_array_size[map_to][1] - 1; m++) { + double dntemp = 3/(n3b_knots_array[map_to][1][m + 4] - + n3b_knots_array[map_to][1][m + 1]); + for (int n = 0; n < n3b_coeff_array_size[map_to][2]; n++) { + coeff_for_der_ik[map_to][l][m][n] = + ((n3b_coeff_array[map_to][l][m + 1][n] - + n3b_coeff_array[map_to][l][m][n])*dntemp); + } + } + } + + //--deri_basis_ij + for (int l = 1; l < n3b_knots_array_size[map_to][2] - 1; l++) + knots_for_der[2][l-1] = n3b_knots_array[map_to][2][l]; + + for (int l = 0; l < n3b_coeff_array_size[map_to][0] - 1; l++) { + double dntemp = 3/(n3b_knots_array[map_to][2][l + 4] - + n3b_knots_array[map_to][2][l + 1]); + for(int m = 0; m < n3b_coeff_array_size[map_to][1]; m++) { + for(int n = 0; n < n3b_coeff_array_size[map_to][2]; n++) { + coeff_for_der_ij[map_to][l][m][n] = + ((n3b_coeff_array[map_to][l + 1][m][n] - + n3b_coeff_array[map_to][l][m][n]) * dntemp); + } + } + } + + for (int l = 0; l < n3b_coeff_array_size[map_to][0] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri_ij(lmp, &knots_for_der[2][l], 1); + for (int cc = 0; cc < 9; cc++) { + cached_constants_3b_deri[map_to][0][l][cc] = bspline_basis_deri_ij.constants[cc]; + } + } + + for (int l = 0; l < n3b_coeff_array_size[map_to][1] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri_ik(lmp, &knots_for_der[1][l], 1); + for (int cc = 0; cc < 9; cc++) { + cached_constants_3b_deri[map_to][1][l][cc] = bspline_basis_deri_ik.constants[cc]; + } + } + + for (int l = 0; l < n3b_coeff_array_size[map_to][2] - 1; l++) { + uf3_bspline_basis2 bspline_basis_deri_jk(lmp, &knots_for_der[0][l], 1); + for (int cc = 0; cc < 9; cc++) { + cached_constants_3b_deri[map_to][2][l][cc] = bspline_basis_deri_jk.constants[cc]; + } + } + + memory->destroy(knots_for_der); + } + } + } +} + +void PairUF3::compute(int eflag, int vflag) +{ + int i, j, k, ii, jj, kk, inum, jnum, itype, jtype, ktype; + double xtmp, ytmp, ztmp, delx, dely, delz, evdwl, fpair, fx, fy, fz; + double del_rji[3], del_rki[3], del_rkj[3]; + double fij[3], fik[3], fjk[3]; + double fji[3], fki[3], fkj[3]; + double Fi[3], Fj[3], Fk[3]; + double rsq, rij, rik, rjk; + double rij_sq, rik_sq, rjk_sq; + int *ilist, *jlist, *numneigh, **firstneigh; + + ev_init(eflag, vflag); + + double **x = atom->x; + double **f = atom->f; + int *type = atom->type; + int nlocal = atom->nlocal; + int newton_pair = force->newton_pair; + + inum = list->inum; + ilist = list->ilist; + numneigh = list->numneigh; + firstneigh = list->firstneigh; + // loop over neighbors of my atoms + for (ii = 0; ii < inum; ii++) { + evdwl = 0; + i = ilist[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + itype = type[i]; + jlist = firstneigh[i]; + jnum = numneigh[i]; + int numshort = 0; + for (jj = 0; jj < jnum; jj++) { + fx = 0; + fy = 0; + fz = 0; + j = jlist[jj]; + j &= NEIGHMASK; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + + rsq = delx * delx + dely * dely + delz * delz; + jtype = type[j]; + if (rsq < cutsq[itype][jtype]) { + rij = sqrt(rsq); + + if (pot_3b) { + if (rij <= cut_3b_list[itype][jtype]) { + neighshort[numshort] = j; + if (numshort >= maxshort - 1) { + maxshort += maxshort / 2; + memory->grow(neighshort, maxshort, "pair:neighshort"); + } + numshort = numshort + 1; + } + } + + int knot_start_index = (this->*get_starting_index_2b)(itype,jtype,rij); + + double force_2b = cached_constants_2b_deri[itype][jtype][knot_start_index - 1][0]; + force_2b += rij*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][1]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][2]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 2][3]; + force_2b += rij*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][4]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][5]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 3][6]; + force_2b += rij*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][7]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][8]; + + fpair = -1 * force_2b / rij; + + fx = delx * fpair; + fy = dely * fpair; + fz = delz * fpair; + + f[i][0] += fx; + f[i][1] += fy; + f[i][2] += fz; + f[j][0] -= fx; + f[j][1] -= fy; + f[j][2] -= fz; + + if (eflag) { + double rth = rsq*rij; + evdwl = cached_constants_2b[itype][jtype][knot_start_index][0]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index][1]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index][2]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index][3]; + evdwl += cached_constants_2b[itype][jtype][knot_start_index-1][4]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index-1][5]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index-1][6]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index-1][7]; + evdwl += cached_constants_2b[itype][jtype][knot_start_index-2][8]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index-2][9]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index-2][10]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index-2][11]; + evdwl += cached_constants_2b[itype][jtype][knot_start_index-3][12]; + evdwl += rij*cached_constants_2b[itype][jtype][knot_start_index-3][13]; + evdwl += rsq*cached_constants_2b[itype][jtype][knot_start_index-3][14]; + evdwl += rth*cached_constants_2b[itype][jtype][knot_start_index-3][15]; + }; + + if (evflag) { + ev_tally_xyz(i, j, nlocal, newton_pair, evdwl, 0.0, fx, fy, fz, delx, dely, delz); + + // Centroid Stress + if (vflag_either && cvflag_atom) { + double v[6]; + + v[0] = delx * fx; + v[1] = dely * fy; + v[2] = delz * fz; + v[3] = delx * fy; + v[4] = delx * fz; + v[5] = dely * fz; + + cvatom[i][0] += 0.5 * v[0]; + cvatom[i][1] += 0.5 * v[1]; + cvatom[i][2] += 0.5 * v[2]; + cvatom[i][3] += 0.5 * v[3]; + cvatom[i][4] += 0.5 * v[4]; + cvatom[i][5] += 0.5 * v[5]; + cvatom[i][6] += 0.5 * v[3]; + cvatom[i][7] += 0.5 * v[4]; + cvatom[i][8] += 0.5 * v[5]; + + cvatom[j][0] += 0.5 * v[0]; + cvatom[j][1] += 0.5 * v[1]; + cvatom[j][2] += 0.5 * v[2]; + cvatom[j][3] += 0.5 * v[3]; + cvatom[j][4] += 0.5 * v[4]; + cvatom[j][5] += 0.5 * v[5]; + cvatom[j][6] += 0.5 * v[3]; + cvatom[j][7] += 0.5 * v[4]; + cvatom[j][8] += 0.5 * v[5]; + } + } + } + } + + // 3-body interaction + // jth atom + jnum = numshort - 1; + for (jj = 0; jj < jnum; jj++) { + fij[0] = fji[0] = 0; + fij[1] = fji[1] = 0; + fij[2] = fji[2] = 0; + j = neighshort[jj]; + jtype = type[j]; + del_rji[0] = x[j][0] - xtmp; + del_rji[1] = x[j][1] - ytmp; + del_rji[2] = x[j][2] - ztmp; + rij_sq = (del_rji[0] * del_rji[0]) + (del_rji[1] * del_rji[1]) + (del_rji[2] * del_rji[2]); + rij = sqrt(rij_sq); + + // kth atom + for (kk = jj + 1; kk < numshort; kk++) { + + fik[0] = fki[0] = 0; + fik[1] = fki[1] = 0; + fik[2] = fki[2] = 0; + + fjk[0] = fkj[0] = 0; + fjk[1] = fkj[1] = 0; + fjk[2] = fkj[2] = 0; + + k = neighshort[kk]; + ktype = type[k]; + del_rki[0] = x[k][0] - xtmp; + del_rki[1] = x[k][1] - ytmp; + del_rki[2] = x[k][2] - ztmp; + rik_sq = (del_rki[0] * del_rki[0]) + (del_rki[1] * del_rki[1]) + (del_rki[2] * del_rki[2]); + rik = sqrt(rik_sq); + + if ((rij <= cut_3b[itype][jtype][ktype]) && + (rik <= cut_3b[itype][ktype][jtype]) && + (rij >= min_cut_3b[itype][jtype][ktype][2]) && + (rik >= min_cut_3b[itype][jtype][ktype][1])) { + + del_rkj[0] = x[k][0] - x[j][0]; + del_rkj[1] = x[k][1] - x[j][1]; + del_rkj[2] = x[k][2] - x[j][2]; + + rjk_sq = (del_rkj[0] * del_rkj[0]) + (del_rkj[1] * del_rkj[1]) + (del_rkj[2] * del_rkj[2]); + rjk = sqrt(rjk_sq); + + if (rjk >= min_cut_3b[itype][jtype][ktype][0]) { + double rij_th = rij*rij_sq; + double rik_th = rik*rik_sq; + double rjk_th = rjk*rjk_sq; + + int map_to = map_3b[itype][jtype][ktype]; + int knot_start_index_ij = (this->*get_starting_index_3b)(itype,jtype,ktype,rij,2); + int knot_start_index_ik = (this->*get_starting_index_3b)(itype,jtype,ktype,rik,1); + int knot_start_index_jk = (this->*get_starting_index_3b)(itype,jtype,ktype,rjk,0); + double basis_ij[4]; + double basis_ik[4]; + double basis_jk[4]; + double basis_ij_der[3]; + double basis_ik_der[3]; + double basis_jk_der[3]; + + //--------------basis_ij + basis_ij[0] = cached_constants_3b[map_to][0][knot_start_index_ij - 3][12]; + basis_ij[0] += rij*cached_constants_3b[map_to][0][knot_start_index_ij - 3][13]; + basis_ij[0] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij - 3][14]; + basis_ij[0] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij - 3][15]; + + basis_ij[1] = cached_constants_3b[map_to][0][knot_start_index_ij - 2][8]; + basis_ij[1] += rij*cached_constants_3b[map_to][0][knot_start_index_ij - 2][9]; + basis_ij[1] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij - 2][10]; + basis_ij[1] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij - 2][11]; + + basis_ij[2] = cached_constants_3b[map_to][0][knot_start_index_ij - 1][4]; + basis_ij[2] += rij*cached_constants_3b[map_to][0][knot_start_index_ij - 1][5]; + basis_ij[2] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij - 1][6]; + basis_ij[2] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij - 1][7]; + + basis_ij[3] = cached_constants_3b[map_to][0][knot_start_index_ij][0]; + basis_ij[3] += rij*cached_constants_3b[map_to][0][knot_start_index_ij][1]; + basis_ij[3] += rij_sq*cached_constants_3b[map_to][0][knot_start_index_ij][2]; + basis_ij[3] += rij_th*cached_constants_3b[map_to][0][knot_start_index_ij][3]; + + //--------------basis_ik + basis_ik[0] = cached_constants_3b[map_to][1][knot_start_index_ik - 3][12]; + basis_ik[0] += rik*cached_constants_3b[map_to][1][knot_start_index_ik - 3][13]; + basis_ik[0] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik - 3][14]; + basis_ik[0] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik - 3][15]; + + basis_ik[1] = cached_constants_3b[map_to][1][knot_start_index_ik - 2][8]; + basis_ik[1] += rik*cached_constants_3b[map_to][1][knot_start_index_ik - 2][9]; + basis_ik[1] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik - 2][10]; + basis_ik[1] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik - 2][11]; + + basis_ik[2] = cached_constants_3b[map_to][1][knot_start_index_ik - 1][4]; + basis_ik[2] += rik*cached_constants_3b[map_to][1][knot_start_index_ik - 1][5]; + basis_ik[2] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik - 1][6]; + basis_ik[2] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik - 1][7]; + + basis_ik[3] = cached_constants_3b[map_to][1][knot_start_index_ik][0]; + basis_ik[3] += rik*cached_constants_3b[map_to][1][knot_start_index_ik][1]; + basis_ik[3] += rik_sq*cached_constants_3b[map_to][1][knot_start_index_ik][2]; + basis_ik[3] += rik_th*cached_constants_3b[map_to][1][knot_start_index_ik][3]; + + //--------------basis_jk + basis_jk[0] = cached_constants_3b[map_to][2][knot_start_index_jk - 3][12]; + basis_jk[0] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk - 3][13]; + basis_jk[0] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk - 3][14]; + basis_jk[0] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk - 3][15]; + + basis_jk[1] = cached_constants_3b[map_to][2][knot_start_index_jk - 2][8]; + basis_jk[1] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk - 2][9]; + basis_jk[1] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk - 2][10]; + basis_jk[1] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk - 2][11]; + + basis_jk[2] = cached_constants_3b[map_to][2][knot_start_index_jk - 1][4]; + basis_jk[2] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk - 1][5]; + basis_jk[2] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk - 1][6]; + basis_jk[2] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk - 1][7]; + + basis_jk[3] = cached_constants_3b[map_to][2][knot_start_index_jk][0]; + basis_jk[3] += rjk*cached_constants_3b[map_to][2][knot_start_index_jk][1]; + basis_jk[3] += rjk_sq*cached_constants_3b[map_to][2][knot_start_index_jk][2]; + basis_jk[3] += rjk_th*cached_constants_3b[map_to][2][knot_start_index_jk][3]; + + //----------------basis_ij_der + basis_ij_der[0] = cached_constants_3b_deri[map_to][0][knot_start_index_ij - 3][6]; + basis_ij_der[0] += rij*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 3][7]; + basis_ij_der[0] += rij_sq*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 3][8]; + + basis_ij_der[1] = cached_constants_3b_deri[map_to][0][knot_start_index_ij - 2][3]; + basis_ij_der[1] += rij*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 2][4]; + basis_ij_der[1] += rij_sq*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 2][5]; + + basis_ij_der[2] = cached_constants_3b_deri[map_to][0][knot_start_index_ij - 1][0]; + basis_ij_der[2] += rij*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 1][1]; + basis_ij_der[2] += rij_sq*cached_constants_3b_deri[map_to][0][knot_start_index_ij - 1][2]; + + //----------------basis_ik_der + basis_ik_der[0] = cached_constants_3b_deri[map_to][1][knot_start_index_ik - 3][6]; + basis_ik_der[0] += rik*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 3][7]; + basis_ik_der[0] += rik_sq*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 3][8]; + + basis_ik_der[1] = cached_constants_3b_deri[map_to][1][knot_start_index_ik - 2][3]; + basis_ik_der[1] += rik*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 2][4]; + basis_ik_der[1] += rik_sq*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 2][5]; + + basis_ik_der[2] = cached_constants_3b_deri[map_to][1][knot_start_index_ik - 1][0]; + basis_ik_der[2] += rik*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 1][1]; + basis_ik_der[2] += rik_sq*cached_constants_3b_deri[map_to][1][knot_start_index_ik - 1][2]; + + //----------------basis_jk_der + basis_jk_der[0] = cached_constants_3b_deri[map_to][2][knot_start_index_jk - 3][6]; + basis_jk_der[0] += rjk*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 3][7]; + basis_jk_der[0] += rjk_sq*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 3][8]; + + basis_jk_der[1] = cached_constants_3b_deri[map_to][2][knot_start_index_jk - 2][3]; + basis_jk_der[1] += rjk*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 2][4]; + basis_jk_der[1] += rjk_sq*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 2][5]; + + basis_jk_der[2] = cached_constants_3b_deri[map_to][2][knot_start_index_jk - 1][0]; + basis_jk_der[2] += rjk*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 1][1]; + basis_jk_der[2] += rjk_sq*cached_constants_3b_deri[map_to][2][knot_start_index_jk - 1][2]; + + double triangle_eval[4] = {0,0,0,0}; + + int iknot_ij = knot_start_index_ij - 3; + int iknot_ik = knot_start_index_ik - 3; + int iknot_jk = knot_start_index_jk - 3; + + for (int l = 0; l < 3; l++) { + const double basis_ij_der_i = basis_ij_der[l]; + for (int m = 0; m < 4; m++) { + const double factor = basis_ij_der_i * basis_ik[m]; + const double* slice = + &coeff_for_der_ij[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[4]; + tmp[0] = slice[0] * basis_jk[0]; + tmp[1] = slice[1] * basis_jk[1]; + tmp[2] = slice[2] * basis_jk[2]; + tmp[3] = slice[3] * basis_jk[3]; + double sum = tmp[0] + tmp[1] + tmp[2] + tmp[3]; + triangle_eval[1] += factor * sum; + } + } + + for (int l = 0; l < 4; l++) { + const double basis_ij_i = basis_ij[l]; + for (int m = 0; m < 3; m++) { + const double factor = basis_ij_i * basis_ik_der[m]; + const double* slice = + &coeff_for_der_ik[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[4]; + tmp[0] = slice[0] * basis_jk[0]; + tmp[1] = slice[1] * basis_jk[1]; + tmp[2] = slice[2] * basis_jk[2]; + tmp[3] = slice[3] * basis_jk[3]; + double sum = tmp[0] + tmp[1] + tmp[2] + tmp[3]; + triangle_eval[2] += factor * sum; + } + } + + for (int l = 0; l < 4; l++) { + const double basis_ij_i = basis_ij[l]; + for (int m = 0; m < 4; m++) { + const double factor = basis_ij_i * basis_ik[m]; + const double* slice = + &coeff_for_der_jk[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[3]; + tmp[0] = slice[0] * basis_jk_der[0]; + tmp[1] = slice[1] * basis_jk_der[1]; + tmp[2] = slice[2] * basis_jk_der[2]; + double sum = tmp[0] + tmp[1] + tmp[2]; + triangle_eval[3] += factor * sum; + } + } + + fij[0] = *(triangle_eval + 1) * (del_rji[0] / rij); + fji[0] = -fij[0]; + fik[0] = *(triangle_eval + 2) * (del_rki[0] / rik); + fki[0] = -fik[0]; + fjk[0] = *(triangle_eval + 3) * (del_rkj[0] / rjk); + fkj[0] = -fjk[0]; + + fij[1] = *(triangle_eval + 1) * (del_rji[1] / rij); + fji[1] = -fij[1]; + fik[1] = *(triangle_eval + 2) * (del_rki[1] / rik); + fki[1] = -fik[1]; + fjk[1] = *(triangle_eval + 3) * (del_rkj[1] / rjk); + fkj[1] = -fjk[1]; + + fij[2] = *(triangle_eval + 1) * (del_rji[2] / rij); + fji[2] = -fij[2]; + fik[2] = *(triangle_eval + 2) * (del_rki[2] / rik); + fki[2] = -fik[2]; + fjk[2] = *(triangle_eval + 3) * (del_rkj[2] / rjk); + fkj[2] = -fjk[2]; + + Fi[0] = fij[0] + fik[0]; + Fi[1] = fij[1] + fik[1]; + Fi[2] = fij[2] + fik[2]; + f[i][0] += Fi[0]; + f[i][1] += Fi[1]; + f[i][2] += Fi[2]; + + Fj[0] = fji[0] + fjk[0]; + Fj[1] = fji[1] + fjk[1]; + Fj[2] = fji[2] + fjk[2]; + f[j][0] += Fj[0]; + f[j][1] += Fj[1]; + f[j][2] += Fj[2]; + + Fk[0] = fki[0] + fkj[0]; + Fk[1] = fki[1] + fkj[1]; + Fk[2] = fki[2] + fkj[2]; + f[k][0] += Fk[0]; + f[k][1] += Fk[1]; + f[k][2] += Fk[2]; + + if (eflag) { + for (int l = 0; l < 4; l++) { + const double basis_ij_i = basis_ij[l]; + for (int m = 0; m < 4; m++) { + const double factor = basis_ij_i * basis_ik[m]; + const double* slice = + &n3b_coeff_array[map_to][iknot_ij + l][iknot_ik + m][iknot_jk]; + double tmp[4]; + tmp[0] = slice[0] * basis_jk[0]; + tmp[1] = slice[1] * basis_jk[1]; + tmp[2] = slice[2] * basis_jk[2]; + tmp[3] = slice[3] * basis_jk[3]; + double sum = tmp[0] + tmp[1] + tmp[2] + tmp[3]; + triangle_eval[0] += factor * sum; + } + } + evdwl = *triangle_eval; + } + + if (evflag) { + ev_tally3(i, j, k, evdwl, 0, Fj, Fk, del_rji, del_rki); + // Centroid stress 3-body term + if (vflag_either && cvflag_atom) { + double ric[3]; + ric[0] = THIRD * (-del_rji[0] - del_rki[0]); + ric[1] = THIRD * (-del_rji[1] - del_rki[1]); + ric[2] = THIRD * (-del_rji[2] - del_rki[2]); + + cvatom[i][0] += ric[0] * Fi[0]; + cvatom[i][1] += ric[1] * Fi[1]; + cvatom[i][2] += ric[2] * Fi[2]; + cvatom[i][3] += ric[0] * Fi[1]; + cvatom[i][4] += ric[0] * Fi[2]; + cvatom[i][5] += ric[1] * Fi[2]; + cvatom[i][6] += ric[1] * Fi[0]; + cvatom[i][7] += ric[2] * Fi[0]; + cvatom[i][8] += ric[2] * Fi[1]; + + double rjc[3]; + rjc[0] = THIRD * (del_rji[0] - del_rkj[0]); + rjc[1] = THIRD * (del_rji[1] - del_rkj[1]); + rjc[2] = THIRD * (del_rji[2] - del_rkj[2]); + + cvatom[j][0] += rjc[0] * Fj[0]; + cvatom[j][1] += rjc[1] * Fj[1]; + cvatom[j][2] += rjc[2] * Fj[2]; + cvatom[j][3] += rjc[0] * Fj[1]; + cvatom[j][4] += rjc[0] * Fj[2]; + cvatom[j][5] += rjc[1] * Fj[2]; + cvatom[j][6] += rjc[1] * Fj[0]; + cvatom[j][7] += rjc[2] * Fj[0]; + cvatom[j][8] += rjc[2] * Fj[1]; + + double rkc[3]; + rkc[0] = THIRD * (del_rki[0] + del_rkj[0]); + rkc[1] = THIRD * (del_rki[1] + del_rkj[1]); + rkc[2] = THIRD * (del_rki[2] + del_rkj[2]); + + cvatom[k][0] += rkc[0] * Fk[0]; + cvatom[k][1] += rkc[1] * Fk[1]; + cvatom[k][2] += rkc[2] * Fk[2]; + cvatom[k][3] += rkc[0] * Fk[1]; + cvatom[k][4] += rkc[0] * Fk[2]; + cvatom[k][5] += rkc[1] * Fk[2]; + cvatom[k][6] += rkc[1] * Fk[0]; + cvatom[k][7] += rkc[2] * Fk[0]; + cvatom[k][8] += rkc[2] * Fk[1]; + } + } + } + } + } + } + } + if (vflag_fdotr) virial_fdotr_compute(); +} + +double PairUF3::single(int /*i*/, int /*j*/, int itype, int jtype, double rsq, + double /*factor_coul*/, double factor_lj, double &fforce) +{ + double value = 0.0; + double r = sqrt(rsq); + + if (r < cut[itype][jtype]) { + int knot_start_index = (this->*get_starting_index_2b)(itype,jtype,r); + + double force_2b = cached_constants_2b_deri[itype][jtype][knot_start_index - 1][0]; + force_2b += r*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][1]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 1][2]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 2][3]; + force_2b += r*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][4]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 2][5]; + force_2b += cached_constants_2b_deri[itype][jtype][knot_start_index - 3][6]; + force_2b += r*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][7]; + force_2b += rsq*cached_constants_2b_deri[itype][jtype][knot_start_index - 3][8]; + fforce = factor_lj * force_2b; + + double rth = rsq*r; + value = cached_constants_2b[itype][jtype][knot_start_index][0]; + value += r*cached_constants_2b[itype][jtype][knot_start_index][1]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index][2]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index][3]; + value += cached_constants_2b[itype][jtype][knot_start_index-1][4]; + value += r*cached_constants_2b[itype][jtype][knot_start_index-1][5]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index-1][6]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index-1][7]; + value += cached_constants_2b[itype][jtype][knot_start_index-2][8]; + value += r*cached_constants_2b[itype][jtype][knot_start_index-2][9]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index-2][10]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index-2][11]; + value += cached_constants_2b[itype][jtype][knot_start_index-3][12]; + value += r*cached_constants_2b[itype][jtype][knot_start_index-3][13]; + value += rsq*cached_constants_2b[itype][jtype][knot_start_index-3][14]; + value += rth*cached_constants_2b[itype][jtype][knot_start_index-3][15]; + } + + return factor_lj * value; +} + +double PairUF3::memory_usage() +{ + const int num_of_elements = atom->ntypes; + double bytes = Pair::memory_usage(); + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(int); //***setflag_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(int); //knot_spacing_type_2b + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(int); //knot_spacing_type_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //cut + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(double); //***cut_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //cut_3b_list + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * 3 * + sizeof(double); //min_cut_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(double); //knot_spacing_2b + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (num_of_elements + 1) * + sizeof(double); //knot_spacing_3b + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_knots_2b * + sizeof(double); //n2b_knots_array + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_coeff_2b * + sizeof(double); //n2b_coeff_array + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(int); //n2b_knots_array_size + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * sizeof(int); //n2b_coeff_array_size + + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * max_num_coeff_2b * + 16 * sizeof(double); //cached_constants_2b, + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * (max_num_coeff_2b-1) * + 9 * sizeof(double); //cached_constants_2b_deri + + + if (pot_3b) { + bytes += (double) (num_of_elements + 1) * (num_of_elements + 1) * + (num_of_elements + 1) * sizeof(int); //map_3b + + bytes += (double) tot_interaction_count_3b * 3 * max_num_knots_3b * sizeof(double); //n3b_knots_array + bytes += (double) tot_interaction_count_3b * max_num_coeff_3b * max_num_coeff_3b * + max_num_coeff_3b * sizeof(double); //n3b_coeff_array + + bytes += (double) tot_interaction_count_3b * 3 * sizeof(int); //n3b_knots_array_size + bytes += (double) tot_interaction_count_3b * 3 * sizeof(int); //n3b_coeff_array_size + + bytes += (double) tot_interaction_count_3b * max_num_coeff_3b * max_num_coeff_3b + * max_num_coeff_3b * 3 * sizeof(double); //coeff_for_der_jk coeff_for_der_ik coeff_for_der_ij + + bytes += (double) tot_interaction_count_3b * 3 * max_num_coeff_3b * 16 + * sizeof(double); //cached_constants_3b + bytes += (double) tot_interaction_count_3b * 3 * (max_num_coeff_3b - 1) * 16 + * sizeof(double); //cached_constants_3b_deri + + } + + bytes += (double) maxshort * sizeof(int); //neighshort + + bytes += (double) 6 * sizeof(int); //maxshort, bsplines_created, nbody_flag, + //max_num_knots_2b, max_num_coeff_2b, + //max_num_knots_3b, max_num_coeff_3b + bytes += (double) 1 * sizeof(bool); //pot_3b + + return bytes; +} diff --git a/src/ML-UF3/pair_uf3.h b/src/ML-UF3/pair_uf3.h new file mode 100644 index 0000000000..9c6ec5022f --- /dev/null +++ b/src/ML-UF3/pair_uf3.h @@ -0,0 +1,95 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + https://www.lammps.org/, Sandia National Laboratories + LAMMPS development team: developers@lammps.org + + 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. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: Ajinkya Hire (Univ. of Florida), + Hendrik Kraß (Univ. of Constance), + Matthias Rupp (Luxembourg Institute of Science and Technology), + Richard Hennig (Univ of Florida) +---------------------------------------------------------------------- */ + +#ifdef PAIR_CLASS +// clang-format off +PairStyle(uf3,PairUF3); +// clang-format on +#else + +#ifndef LMP_PAIR_UF3_H +#define LMP_PAIR_UF3_H + +#include "pair.h" + +namespace LAMMPS_NS { + +class PairUF3 : public Pair { + public: + PairUF3(class LAMMPS *); + ~PairUF3() override; + void compute(int, int) override; + void settings(int, char **) override; + void coeff(int, char **) override; + void init_style() override; + void init_list(int, class NeighList *) override; // needed for ptr to full neigh list + double init_one(int, int) override; // needed for cutoff radius for neighbour list + double single(int, int, int, int, double, double, double, double &) override; + + double memory_usage() override; + + protected: + int ***setflag_3b, **knot_spacing_type_2b, ***knot_spacing_type_3b; + double **cut, ***cut_3b, **cut_3b_list, ****min_cut_3b; + double **knot_spacing_2b, ****knot_spacing_3b; + + double ***n2b_knots_array, ***n2b_coeff_array; + int **n2b_knots_array_size, **n2b_coeff_array_size; + double ****cached_constants_2b, ****cached_constants_2b_deri; + + int ***map_3b; + double ***n3b_knots_array, ****n3b_coeff_array; + int **n3b_knots_array_size, **n3b_coeff_array_size; + double ****coeff_for_der_jk, ****coeff_for_der_ik,****coeff_for_der_ij; + double ****cached_constants_3b, ****cached_constants_3b_deri; + + int *neighshort, maxshort; // short neighbor list array for 3body interaction + + void uf3_read_unified_pot_file(char *potf_name); + void communicate(); + int bsplines_created; + bool pot_3b; + virtual void allocate(); + void create_bsplines(); + void create_cached_constants_2b(); + void create_cached_constants_3b(); + + int get_starting_index_uniform_2b(int i, int j, double r); + int get_starting_index_uniform_3b(int i, int j, int k, double r, int knot_dim); + + int get_starting_index_nonuniform_2b(int i, int j, double r); + int get_starting_index_nonuniform_3b(int i, int j, int k, double r, int knot_dim); + + int (PairUF3::*get_starting_index_2b)(int i, int j, double r); + int (PairUF3::*get_starting_index_3b)(int i, int j, int k, double r, int knot_dim); + + int nbody_flag = 3; + int max_num_knots_2b = 0; + int max_num_coeff_2b = 0; + int max_num_knots_3b = 0; + int max_num_coeff_3b = 0; + int tot_interaction_count_3b = 0; +}; + +} // namespace LAMMPS_NS + +#endif +#endif + diff --git a/src/ML-UF3/uf3_bspline_basis2.cpp b/src/ML-UF3/uf3_bspline_basis2.cpp new file mode 100644 index 0000000000..bb73e07970 --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis2.cpp @@ -0,0 +1,111 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + 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 "uf3_bspline_basis2.h" + +#include "math_special.h" + +using namespace LAMMPS_NS; +using MathSpecial::square; + +// Constructor +// Initializes coefficients and knots +// Requires [knots] to have length 4 +uf3_bspline_basis2::uf3_bspline_basis2(LAMMPS *ulmp, const double *knots, double coefficient) +{ + lmp = ulmp; + + double c0, c1, c2; + + c0 = coefficient + * (square(knots[0]) + / (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + c1 = coefficient * + (-2.0 * knots[0] / + (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + c2 = coefficient * + (1.0 / (square(knots[0]) - knots[0] * knots[1] - knots[0] * knots[2] + knots[1] * knots[2])); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + constants[0] = c0; + constants[1] = c1; + constants[2] = c2; + c0 = coefficient * + (-knots[1] * knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + knots[0] * knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + c1 = coefficient * + (knots[1] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[3] / + (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) + + knots[0] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2])) + + knots[2] / + (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + c2 = coefficient * + (-1.0 / (square(knots[1]) - knots[1] * knots[2] - knots[1] * knots[3] + knots[2] * knots[3]) - + 1.0 / (knots[0] * knots[1] - knots[0] * knots[2] - knots[1] * knots[2] + square(knots[2]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + constants[3] = c0; + constants[4] = c1; + constants[5] = c2; + c0 = coefficient * + (square(knots[3]) / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + c1 = coefficient * + (-2.0 * knots[3] / + (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + c2 = coefficient * + (1.0 / (knots[1] * knots[2] - knots[1] * knots[3] - knots[2] * knots[3] + square(knots[3]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + constants[6] = c0; + constants[7] = c1; + constants[8] = c2; +} + +uf3_bspline_basis2::~uf3_bspline_basis2() {} + +// Evaluate outer-left part of spline +double uf3_bspline_basis2::eval0(double rsq, double r) +{ + return rsq * constants[2] + r * constants[1] + constants[0]; +} + +// Evaluate center-left part of spline +double uf3_bspline_basis2::eval1(double rsq, double r) +{ + return rsq * constants[5] + r * constants[4] + constants[3]; +} + +// Evaluate center-right part of spline +double uf3_bspline_basis2::eval2(double rsq, double r) +{ + return rsq * constants[8] + r * constants[7] + constants[6]; +} + +double uf3_bspline_basis2::memory_usage() +{ + double bytes = 0; + + bytes += (double)9*sizeof(double); + + return bytes; +} diff --git a/src/ML-UF3/uf3_bspline_basis2.h b/src/ML-UF3/uf3_bspline_basis2.h new file mode 100644 index 0000000000..b577e0c92a --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis2.h @@ -0,0 +1,41 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + 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 "pointers.h" + +#include + +#ifndef UF3_BSPLINE_BASIS2_H +#define UF3_BSPLINE_BASIS2_H + +namespace LAMMPS_NS { + +class uf3_bspline_basis2 { + private: + LAMMPS *lmp; + //std::vector constants; + + public: + uf3_bspline_basis2(LAMMPS *ulmp, const double *knots, double coefficient); + ~uf3_bspline_basis2(); + //std::vector constants; + double constants[9] = {}; + double eval0(double, double); + double eval1(double, double); + double eval2(double, double); + + double memory_usage(); +}; + +} // namespace LAMMPS_NS +#endif diff --git a/src/ML-UF3/uf3_bspline_basis3.cpp b/src/ML-UF3/uf3_bspline_basis3.cpp new file mode 100644 index 0000000000..b2c7aa2acb --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis3.cpp @@ -0,0 +1,355 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + 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 "uf3_bspline_basis3.h" + +#include "math_special.h" + +using namespace LAMMPS_NS; +using MathSpecial::cube; +using MathSpecial::square; + +// Constructor +// Initializes coefficients and knots +// [knots] needs to have length 4 +uf3_bspline_basis3::uf3_bspline_basis3(LAMMPS *ulmp, const double *knots, double coefficient) +{ + lmp = ulmp; + + double c0, c1, c2, c3; + + c0 = coefficient * + (-cube(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + c1 = coefficient * + (3.0 * square(knots[0]) / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + c2 = coefficient * + (-3.0 * knots[0] / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + c3 = coefficient * + (1.0 / + (-cube(knots[0]) + square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + square(knots[0]) * knots[3] - knots[0] * knots[1] * knots[2] - + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[3])); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[0] = c0; + constants[1] = c1; + constants[2] = c2; + constants[3] = c3; + c0 = coefficient * + (square(knots[1]) * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + square(knots[0]) * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] * knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + c1 = coefficient * + (-square(knots[1]) / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 2.0 * knots[1] * knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + square(knots[0]) / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 2.0 * knots[0] * knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + knots[0] * knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[0] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) - + knots[1] * knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + c2 = coefficient * + (2.0 * knots[1] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + knots[4] / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) + + 2.0 * knots[0] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[2] / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) + + knots[0] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[1] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3])) + + knots[3] / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + c3 = coefficient * + (-1.0 / + (-cube(knots[1]) + square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + square(knots[1]) * knots[4] - knots[1] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + knots[2] * knots[3] * knots[4]) - + 1.0 / + (-square(knots[0]) * knots[1] + square(knots[0]) * knots[2] + + knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] - + knots[0] * square(knots[2]) - knots[0] * knots[2] * knots[3] - + knots[1] * knots[2] * knots[3] + square(knots[2]) * knots[3]) - + 1.0 / + (-knots[0] * square(knots[1]) + knots[0] * knots[1] * knots[2] + + knots[0] * knots[1] * knots[3] - knots[0] * knots[2] * knots[3] + + square(knots[1]) * knots[3] - knots[1] * knots[2] * knots[3] - + knots[1] * square(knots[3]) + knots[2] * square(knots[3]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[4] = c0; + constants[5] = c1; + constants[6] = c2; + constants[7] = c3; + c0 = coefficient * + (-knots[0] * square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] * knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] * square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + c1 = coefficient * + (2.0 * knots[0] * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + square(knots[3]) / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + knots[1] * knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[1] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + knots[3] * knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 2.0 * knots[2] * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) + + square(knots[4]) / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + c2 = coefficient * + (-knots[0] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + 2.0 * knots[3] / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) - + knots[1] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[3] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[4] / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) - + knots[2] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4])) - + 2.0 * knots[4] / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + c3 = coefficient * + (1.0 / + (-knots[0] * knots[1] * knots[2] + knots[0] * knots[1] * knots[3] + + knots[0] * knots[2] * knots[3] - knots[0] * square(knots[3]) + + knots[1] * knots[2] * knots[3] - knots[1] * square(knots[3]) - + knots[2] * square(knots[3]) + cube(knots[3])) + + 1.0 / + (-square(knots[1]) * knots[2] + square(knots[1]) * knots[3] + + knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] - + knots[1] * square(knots[3]) - knots[1] * knots[3] * knots[4] - + knots[2] * knots[3] * knots[4] + square(knots[3]) * knots[4]) + + 1.0 / + (-knots[1] * square(knots[2]) + knots[1] * knots[2] * knots[3] + + knots[1] * knots[2] * knots[4] - knots[1] * knots[3] * knots[4] + + square(knots[2]) * knots[4] - knots[2] * knots[3] * knots[4] - + knots[2] * square(knots[4]) + knots[3] * square(knots[4]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[8] = c0; + constants[9] = c1; + constants[10] = c2; + constants[11] = c3; + c0 = coefficient * + (cube(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + c1 = coefficient * + (-3.0 * square(knots[4]) / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + c2 = coefficient * + (3.0 * knots[4] / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + c3 = coefficient * + (-1.0 / + (-knots[1] * knots[2] * knots[3] + knots[1] * knots[2] * knots[4] + + knots[1] * knots[3] * knots[4] - knots[1] * square(knots[4]) + + knots[2] * knots[3] * knots[4] - knots[2] * square(knots[4]) - knots[3] * square(knots[4]) + + cube(knots[4]))); + //constants.push_back(c0); + //constants.push_back(c1); + //constants.push_back(c2); + //constants.push_back(c3); + constants[12] = c0; + constants[13] = c1; + constants[14] = c2; + constants[15] = c3; +} + +uf3_bspline_basis3::~uf3_bspline_basis3() {} + +// Evaluate outer-left part of spline +double uf3_bspline_basis3::eval0(double rth, double rsq, double r) +{ + return rth * constants[3] + rsq * constants[2] + r * constants[1] + constants[0]; +} + +// Evaluate center-left part of spline +double uf3_bspline_basis3::eval1(double rth, double rsq, double r) +{ + return rth * constants[7] + rsq * constants[6] + r * constants[5] + constants[4]; +} + +// Evaluate center-right part of spline +double uf3_bspline_basis3::eval2(double rth, double rsq, double r) +{ + return rth * constants[11] + rsq * constants[10] + r * constants[9] + constants[8]; +} + +// Evaluate outer-right part of spline +double uf3_bspline_basis3::eval3(double rth, double rsq, double r) +{ + return rth * constants[15] + rsq * constants[14] + r * constants[13] + constants[12]; +} + +double uf3_bspline_basis3::memory_usage() +{ + double bytes = 0; + + bytes += (double)16*sizeof(double); + + return bytes; +} diff --git a/src/ML-UF3/uf3_bspline_basis3.h b/src/ML-UF3/uf3_bspline_basis3.h new file mode 100644 index 0000000000..70e1bbd2aa --- /dev/null +++ b/src/ML-UF3/uf3_bspline_basis3.h @@ -0,0 +1,42 @@ +// clang-format off +/* ---------------------------------------------------------------------- + lammps - large-scale atomic/molecular massively parallel simulator + https://www.lammps.org/, sandia national laboratories + lammps development team: developers@lammps.org + + 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 "pointers.h" + +#include + +#ifndef UF3_BSPLINE_BASIS3_H +#define UF3_BSPLINE_BASIS3_H + +namespace LAMMPS_NS { + +class uf3_bspline_basis3 { + private: + LAMMPS *lmp; + //std::vector constants; + + public: + uf3_bspline_basis3(LAMMPS *ulmp, const double *knots, double coefficient); + ~uf3_bspline_basis3(); + double constants[16] = {}; + double eval0(double, double, double); + double eval1(double, double, double); + double eval2(double, double, double); + double eval3(double, double, double); + + double memory_usage(); +}; + +} // namespace LAMMPS_NS +#endif diff --git a/src/Makefile b/src/Makefile index b9f1bcbdef..33d7012cae 100644 --- a/src/Makefile +++ b/src/Makefile @@ -104,6 +104,7 @@ PACKAGE = \ ml-quip \ ml-rann \ ml-snap \ + ml-uf3 \ mofff \ molfile \ netcdf \ diff --git a/unittest/force-styles/tests/manybody-pair-uf3.yaml b/unittest/force-styles/tests/manybody-pair-uf3.yaml new file mode 100644 index 0000000000..534b489c78 --- /dev/null +++ b/unittest/force-styles/tests/manybody-pair-uf3.yaml @@ -0,0 +1,158 @@ +--- +lammps_version: 24 Mar 2022 +tags: +date_generated: Tue Nov 28 14:51:03 2023 +epsilon: 1e-09 +skip_tests: +prerequisites: ! | + pair uf3 +pre_commands: ! | + variable newton_pair delete + variable newton_pair index on + variable newton_bond delete +post_commands: ! "" +input_file: in.manybody +pair_style: uf3 3 +pair_coeff: ! | + * * Nb.uf3 Nb Nb Nb Nb Nb Nb Nb Nb +extract: ! "" +natoms: 64 +init_vdwl: -76.14388662099438 +init_coul: 0 +init_stress: ! |2- + 3.1223073343802071e+02 3.1503555484293474e+02 3.2087032195384182e+02 -5.2677023646012433e+00 4.1046361968856566e+01 -2.2705704820012654e-01 +init_forces: ! |2 + 1 -1.0963106297354930e+00 1.9921565797217811e+00 2.0176595423650685e+00 + 2 -2.5744974244934786e+00 8.6065313692841872e-01 -1.3343920771683084e+00 + 3 -7.5762202587571881e-01 -5.1086473746213934e-01 1.7774798100697495e+00 + 4 -1.2651178900120015e+00 2.5481168050091734e+00 1.0332353551246649e+00 + 5 -3.3301075059618213e-02 -8.6936885426915711e-01 -8.0361144939346540e-01 + 6 5.9576544655966956e-02 -5.7569733665007693e-02 -2.5260577270195245e-01 + 7 -7.8223973805485159e-01 -1.5872724248886485e+00 -4.0690678808175756e-01 + 8 1.2837377243355602e-01 6.8616887866365453e-02 3.9279992110159728e-02 + 9 1.3013607224018784e+00 -2.2234802020121042e-01 -2.5820065882172409e+00 + 10 -3.5389541898719123e-01 1.0418734269769769e+00 -6.7534263859128518e-01 + 11 1.5048713773196754e+00 -1.1607474819622305e+00 -4.1343086960946002e-01 + 12 -3.8382036374205457e+00 -1.8953194768009614e+00 -1.5975045274049304e+00 + 13 -5.1243974635480005e-01 2.8005048190722506e+00 -8.5188627697957486e-01 + 14 -4.3260615266171099e-01 1.7104546503175775e+00 4.8896255947620082e-01 + 15 -2.1729171109783061e+00 1.9610148525080886e+00 -1.7550881080125238e+00 + 16 1.3063694982664014e+00 4.0801741093678640e-01 3.3816303090167859e+00 + 17 1.0103076935514768e+00 1.3062727533124225e+00 -3.0591856171743643e+00 + 18 6.6364797168941592e-01 1.3269858177825717e+00 1.0859880651465830e+00 + 19 -4.3237772669504843e-01 1.5179601478654310e+00 -8.9399081937433889e-01 + 20 -4.1109776137187977e+00 4.8942123015814726e-01 3.0324705210921541e-02 + 21 1.0443613152888414e+00 -2.7611218991110009e-01 -3.2334333893456133e+00 + 22 -3.8840635954358733e+00 1.8543888965122868e+00 -2.7044170995178298e+00 + 23 6.4824470795616951e-01 1.1930964693491897e+00 2.3472683895454201e+00 + 24 5.6518885203578750e-01 8.9024666222906623e-01 9.9558410495963645e-01 + 25 -2.3884920507811258e-01 -1.2236748552119361e-01 9.6166740424011798e-04 + 26 -9.4060753459907698e-01 -2.9688412181022056e-01 6.7007032584453752e-01 + 27 5.0390685311588923e-01 -5.8477364114704944e-01 1.6320689076693460e+00 + 28 -8.1564347181637331e-01 1.9951358496458818e-01 3.2879220126777038e+00 + 29 -1.6141037582891811e+00 3.7621933923780954e-01 5.6865013193370151e-01 + 30 -1.2051389982059610e+00 6.5471000907223187e-02 4.6548238063076404e-02 + 31 -8.3799333021355227e-01 -4.3387478264068147e-01 -3.4488785440063413e-01 + 32 -1.8712481645378094e+00 3.1431436055998407e-02 1.1920833582466677e+00 + 33 2.1132311819974756e+00 -7.8762333052322075e-01 2.9319369786200289e+00 + 34 -7.4212669325944880e-01 1.5089695276247311e-01 6.4837671979385259e-01 + 35 4.7876606586762549e-01 -5.2894027298845681e-01 6.5312176822087242e-01 + 36 9.4335406181387005e-01 -7.7270400013223828e-01 4.8506498341757304e-01 + 37 -6.9776523536821422e-01 1.5814045923629079e+00 -1.7145687025150753e+00 + 38 8.3390581678419395e-01 -2.3460369438656256e-01 -8.1845978792256724e-01 + 39 7.9082785819764490e-01 -1.4014821253885934e+00 -3.6171284136791626e+00 + 40 1.5528260681499937e+00 -1.9423308463414859e+00 2.7454733155675826e-01 + 41 1.6230449781222470e-01 4.0254440068393893e-01 -1.0728426614941826e+00 + 42 -2.5760797297848943e+00 -2.3727612877133377e+00 -7.3694736943877159e-01 + 43 -1.4658113294445060e-01 -3.7059450064886161e+00 -2.2611910919567893e-01 + 44 2.6125365540590240e+00 -2.0393457867642488e+00 -1.7353429519549574e-01 + 45 9.1508218547652620e-01 3.2090468646350390e-01 -1.3730810235354041e+00 + 46 -1.2861926535120600e+00 -1.8325412123528377e+00 2.7409156132103112e+00 + 47 5.2214882788544981e-01 9.0702150750152088e-02 1.3758849361839385e+00 + 48 8.7060691872545093e-01 1.0333012026994193e+00 -8.8450736609033931e-01 + 49 1.6921455867723978e-01 -3.2865843167979367e+00 -2.3941507623279072e+00 + 50 1.3029435213640246e+00 1.1566980491369294e+00 -7.8373321422495534e-02 + 51 1.7782167191801962e-01 3.5869618077998595e+00 2.1417753790319543e+00 + 52 3.4939214706481048e+00 -2.4127970289820255e+00 4.1443505260596725e+00 + 53 4.5955988135622799e-01 1.4913218496577223e+00 1.3076728090591363e+00 + 54 7.0400726037068106e-01 -9.4898269328552198e-01 -7.0340401843204670e-01 + 55 1.1319661424097816e+00 -2.3442414589969114e+00 -7.7166661047173946e-01 + 56 7.7292681497946214e-01 5.4202239892193216e-01 -1.0429033367200278e+00 + 57 1.1664627895682855e+00 1.9743121270468009e-01 -3.8302192241786348e-01 + 58 1.3342985230821185e+00 -2.6808564460978351e-01 -9.3875599645237040e-01 + 59 2.1547446695381884e+00 2.5922697594917221e-01 5.5883175680123842e-01 + 60 -1.1202730918333845e+00 -4.0836109063032069e+00 -3.1463158656990915e+00 + 61 7.5258775499505959e-01 1.4742795022217277e+00 -2.2056849646259416e-01 + 62 -2.1194607090574338e+00 9.6304617778841872e-01 -5.8648933450219842e-01 + 63 2.2116847362243819e+00 -6.9485816680348522e-01 -1.2888780585377166e+00 + 64 2.0946943533672595e+00 1.7817828615230797e+00 5.2222100516662051e+00 +run_vdwl: -76.1335425447406 +run_coul: 0 +run_stress: ! |2- + 3.1227357278065733e+02 3.1510436259931976e+02 3.2097655273455166e+02 -5.2932374901106582e+00 4.0956468170617640e+01 1.5018802669860862e-01 +run_forces: ! |2 + 1 -1.1136068191144672e+00 1.9868928531451695e+00 2.0284715885889444e+00 + 2 -2.5718148688418596e+00 8.3532761170683545e-01 -1.3404690568364115e+00 + 3 -7.6676194475345183e-01 -5.0716795928532021e-01 1.7997537336742999e+00 + 4 -1.2720923579033645e+00 2.5419855255447907e+00 1.0258862987566395e+00 + 5 -4.3524258688024453e-02 -8.8004954612209696e-01 -7.9382095260610019e-01 + 6 8.9678254474529928e-02 -5.0742940694548030e-02 -2.4348008365156723e-01 + 7 -7.7364435925734953e-01 -1.5558296160053275e+00 -4.2051790182009818e-01 + 8 1.1143851887986839e-01 7.2497057799814191e-02 3.6624183488660304e-02 + 9 1.2839141188983776e+00 -2.4381166390795905e-01 -2.5926851536420066e+00 + 10 -3.6606370803571597e-01 1.0472513106007628e+00 -6.5579353351390024e-01 + 11 1.4796344435746969e+00 -1.1469564140842350e+00 -4.2766370678100751e-01 + 12 -3.8341194520315707e+00 -1.8877013457658414e+00 -1.5901839974079914e+00 + 13 -4.6650968579193675e-01 2.7962961910932282e+00 -8.2237329615475063e-01 + 14 -4.5362402854231521e-01 1.7048830533652388e+00 4.9165017205992945e-01 + 15 -2.1790730324228798e+00 1.9552241266001966e+00 -1.7453842965710837e+00 + 16 1.3028733875052598e+00 4.1039519382071737e-01 3.3783851223727419e+00 + 17 1.0049330607671125e+00 1.3021263787131616e+00 -3.0544446010601831e+00 + 18 6.3052176771903379e-01 1.3324251901771336e+00 1.0977786571785106e+00 + 19 -4.5964705284123741e-01 1.4850585747490403e+00 -8.9955925151919691e-01 + 20 -4.0843338981113764e+00 4.6843741575982639e-01 4.6947857407657889e-03 + 21 1.0581909871649149e+00 -2.9084634536392007e-01 -3.2540160500533157e+00 + 22 -3.8927799316015426e+00 1.8587085622785937e+00 -2.7125312751977178e+00 + 23 6.6350903350923252e-01 1.1973095378961089e+00 2.3524290511459478e+00 + 24 5.7143336751982488e-01 8.7715571174154605e-01 9.9432218349388102e-01 + 25 -2.4703347062300032e-01 -1.2710986429222224e-01 -1.5749033311971992e-02 + 26 -9.3451713960198701e-01 -2.7778133649821901e-01 6.6713867661147919e-01 + 27 4.9808843860149610e-01 -5.8536464204160887e-01 1.6301914265685915e+00 + 28 -8.2771277475903027e-01 2.1570720428840873e-01 3.2880151472957344e+00 + 29 -1.6048620343875755e+00 3.8486480806372897e-01 5.6967398899129529e-01 + 30 -1.1973961350199096e+00 5.1593120685595580e-02 4.1293831832017062e-02 + 31 -8.4115448475027121e-01 -4.4444260925279200e-01 -3.3858426829044269e-01 + 32 -1.8597577591090164e+00 1.2810085646854485e-02 1.1797889462030640e+00 + 33 2.1159519472471811e+00 -7.8729199670032701e-01 2.9290939088097181e+00 + 34 -7.4188497270023746e-01 1.5645497560825464e-01 6.6033973957472436e-01 + 35 4.8203360935099837e-01 -5.2533146218590032e-01 6.5589135580856639e-01 + 36 9.4037223416537397e-01 -7.6094150822319195e-01 4.5734538655438040e-01 + 37 -6.9906373360474205e-01 1.5746536313295925e+00 -1.7263112595330459e+00 + 38 8.5615988284237132e-01 -2.2431722964535125e-01 -8.0332888328255958e-01 + 39 7.8065137836247200e-01 -1.3983715176027893e+00 -3.6344006191116991e+00 + 40 1.5756754145077525e+00 -1.9548680562354619e+00 2.4171639489710248e-01 + 41 1.7946227297557377e-01 4.1626928569421628e-01 -1.0542445180049111e+00 + 42 -2.5855819286639807e+00 -2.3809591696792194e+00 -7.5444018878363772e-01 + 43 -1.5651979567151933e-01 -3.7133196766462597e+00 -2.3417783002479109e-01 + 44 2.6088788324017109e+00 -2.0370826629544276e+00 -1.7748087222007777e-01 + 45 9.0750981150111454e-01 3.1320571808181447e-01 -1.3570279945304848e+00 + 46 -1.2844641842483453e+00 -1.8271514736854049e+00 2.7652384797305016e+00 + 47 5.2355177969578193e-01 9.5756521123463834e-02 1.3725765177085687e+00 + 48 8.7731662768264451e-01 1.0414860079651591e+00 -9.0032888888892382e-01 + 49 1.4644557239036082e-01 -3.3233388609839873e+00 -2.4250592659007468e+00 + 50 1.3159886335597091e+00 1.1534831728413786e+00 -7.9023436269654135e-02 + 51 1.5810961991408728e-01 3.6227053406802825e+00 2.1622129324293375e+00 + 52 3.5238822669377128e+00 -2.4112486219526210e+00 4.1691651240037055e+00 + 53 4.6279178075715538e-01 1.5349821135997805e+00 1.3624008261786760e+00 + 54 7.0473247201702627e-01 -9.3593778743269240e-01 -7.0089892988315006e-01 + 55 1.1161312397801737e+00 -2.3385526086116117e+00 -7.5151515336312336e-01 + 56 7.6996392118239054e-01 5.3225925152027631e-01 -1.0367667800909899e+00 + 57 1.1705705890031866e+00 1.9234764366836088e-01 -3.8394944778612211e-01 + 58 1.3292217712869172e+00 -2.6420177775466325e-01 -9.5699172084102668e-01 + 59 2.1842122534627268e+00 2.6220494593377625e-01 5.4393643560229021e-01 + 60 -1.1457317620961742e+00 -4.1194027577964150e+00 -3.1920012226137322e+00 + 61 7.5501968427331045e-01 1.4824037577796831e+00 -2.0845605296052469e-01 + 62 -2.1181153169676303e+00 9.6226604332888710e-01 -5.7042120154066434e-01 + 63 2.2161829432347631e+00 -7.0548049758710407e-01 -1.3062673143062038e+00 + 64 2.1263589729936818e+00 1.8281740261598369e+00 5.2543331430537403e+00 +...