Merge branch 'develop' of github.com:lammps/lammps into kk_half_thread

This commit is contained in:
Stan Gerald Moore
2023-12-18 09:03:39 -07:00
318 changed files with 8580 additions and 19272 deletions

View File

@ -118,6 +118,7 @@ KOKKOS, o = OPENMP, t = OPT.
* :doc:`ptm/atom <compute_ptm_atom>`
* :doc:`rattlers/atom <compute_rattlers_atom>`
* :doc:`rdf <compute_rdf>`
* :doc:`reaxff/atom (k) <compute_reaxff_atom>`
* :doc:`reduce <compute_reduce>`
* :doc:`reduce/chunk <compute_reduce_chunk>`
* :doc:`reduce/region <compute_reduce>`

View File

@ -282,6 +282,7 @@ The individual style names on the :doc:`Commands compute <Commands_compute>` pag
* :doc:`ptm/atom <compute_ptm_atom>` - determines the local lattice structure based on the Polyhedral Template Matching method
* :doc:`rattlers/atom <compute_rattlers_atom>` - identify under-coordinated rattler atoms
* :doc:`rdf <compute_rdf>` - radial distribution function :math:`g(r)` histogram of group of atoms
* :doc:`reaxff/atom <compute_reaxff_atom>` - extract ReaxFF bond information
* :doc:`reduce <compute_reduce>` - combine per-atom quantities into a single global value
* :doc:`reduce/chunk <compute_reduce_chunk>` - reduce per-atom quantities within each chunk
* :doc:`reduce/region <compute_reduce>` - same as compute reduce, within a region

View File

@ -0,0 +1,97 @@
.. index:: compute reaxff/atom
.. index:: compute reaxff/atom/kk
compute reaxff/atom command
===========================
Accelerator Variants: *reaxff/atom/kk*
Syntax
""""""
.. code-block:: LAMMPS
compute ID group-ID reaxff/atom attribute args ... keyword value ...
* ID, group-ID are documented in :doc:`compute <compute>` command
* reaxff/atom = name of this compute command
* attribute = *pair*
.. parsed-literal::
*pair* args = nsub
nsub = *n*-instance of a sub-style, if a pair style is used multiple times in a hybrid style
* keyword = *bonds*
.. parsed-literal::
*bonds* value = *no* or *yes*
*no* = ignore list of local bonds
*yes* = include list of local bonds
Examples
""""""""
.. code-block:: LAMMPS
compute 1 all reaxff/atom bonds yes
Description
"""""""""""
.. versionadded:: TBD
Define a computation that extracts bond information computed by the ReaxFF
potential specified by :doc:`pair_style reaxff <pair_reaxff>`.
By default, it produces per-atom data that includes the following columns:
* abo = atom bond order (sum of all bonds)
* nlp = number of lone pairs
* nb = number of bonds
Bonds will only be included if its atoms are in the group.
In addition, if ``bonds`` is set to ``yes``, the compute will also produce a
local array of all bonds on the current processor whose atoms are in the group.
The columns of each entry of this local array are:
* id_i = atom i id of bond
* id_j = atom j id of bond
* bo = bond order of bond
Output info
"""""""""""
This compute calculates a per-atom array and local array depending on the
number of keywords. The number of rows in the local array is the number of
bonds as described above. Both per-atom and local array have 3 columns.
The arrays can be accessed by any command that uses local and per-atom values
from a compute as input. See the :doc:`Howto output <Howto_output>` page for
an overview of LAMMPS output options.
----------
.. include:: accel_styles.rst
----------
Restrictions
""""""""""""
The compute reaxff/atom command requires that the :doc:`pair_style reaxff
<pair_reaxff>` is invoked. This fix is part of the REAXFF package. It is only
enabled if LAMMPS was built with that package. See the :doc:`Build package
<Build_package>` page for more info.
Related commands
""""""""""""""""
:doc:`pair_style reaxff <pair_reaxff>`
Default
"""""""
The option defaults are *bonds* = *no*.

View File

@ -18,7 +18,7 @@ Syntax
* style = *stress/mop* or *stress/mop/profile*
* dir = *x* or *y* or *z* is the direction normal to the plane
* args = argument specific to the compute style
* keywords = *kin* or *conf* or *total* or *pair* or *bond* or *angle* (one or more can be specified)
* keywords = *kin* or *conf* or *total* or *pair* or *bond* or *angle* or *dihedral* (one or more can be specified)
.. parsed-literal::
@ -68,15 +68,13 @@ Verlet algorithm.
.. versionadded:: 15Jun2023
contributions from bond and angle potentials
contributions from bond, angle and dihedral potentials
Between one and six keywords can be used to indicate which contributions
Between one and seven keywords can be used to indicate which contributions
to the stress must be computed: total stress (total), kinetic stress
(kin), configurational stress (conf), stress due to bond stretching
(bond), stress due to angle bending (angle) and/or due to pairwise
non-bonded interactions (pair). The angle keyword is currently
available only for the *stress/mop* command and **not** the
*stress/mop/profile* command.
(bond), stress due to angle bending (angle), stress due to dihedral terms (dihedral)
and/or due to pairwise non-bonded interactions (pair).
NOTE 1: The configurational stress is computed considering all pairs of
atoms where at least one atom belongs to group group-ID.
@ -134,14 +132,9 @@ size does not change in time, and axis-aligned planes.
The method only works with two-body pair interactions, because it
requires the class method ``Pair::single()`` to be implemented, which is
not possible for manybody potentials. In particular, compute
*stress/mop/profile* does not work with more than two-body pair
*stress/mop/profile* and *stress/mop* do not work with more than two-body pair
interactions, long range (kspace) interactions and
angle/dihedral/improper intramolecular interactions. Similarly, compute
*stress/mop* does not work with more than two-body pair interactions,
long range (kspace) interactions and dihedral/improper intramolecular
interactions but works with all bond interactions with the class method
single() implemented and all angle interactions with the class method
born_matrix() implemented.
improper intramolecular interactions.
Related commands
""""""""""""""""

View File

@ -373,7 +373,8 @@ Related commands
:doc:`pair_coeff <pair_coeff>`, :doc:`fix qeq/reaxff <fix_qeq_reaxff>`,
:doc:`fix acks2/reaxff <fix_acks2_reaxff>`, :doc:`fix reaxff/bonds <fix_reaxff_bonds>`,
:doc:`fix reaxff/species <fix_reaxff_species>`
:doc:`fix reaxff/species <fix_reaxff_species>`,
:doc:`compute reaxff/atom <compute_reaxff_atom>`
Default
"""""""

View File

@ -31,8 +31,15 @@ neigh_modify delay 0 every 5 check no
fix 1 all nve
fix 2 all qeq/reaxff 1 0.0 10.0 1.0e-6 reaxff
fix 4 all reaxff/bonds 5 bonds.reaxff
compute bonds all reaxff/atom bonds yes
variable nqeq equal f_2
# dumps out the local bond information
dump 1 all local 5 bonds_local.reaxff c_bonds[1] c_bonds[2] c_bonds[3]
# dumps out the peratom bond information
dump 2 all custom 5 bonds_atom.reaxff id type q c_bonds[*]
thermo 5
thermo_style custom step temp epair etotal press &
v_eb v_ea v_elp v_emol v_ev v_epen v_ecoa &

2
src/.gitignore vendored
View File

@ -633,6 +633,8 @@
/compute_ptm_atom.h
/compute_rattlers_atom.cpp
/compute_rattlers_atom.h
/compute_reaxff_atom.cpp
/compute_reaxff_atom.h
/compute_rigid_local.cpp
/compute_rigid_local.h
/compute_slcsa_atom.cpp

View File

@ -23,6 +23,7 @@
#include "atom_vec.h"
#include "bond.h"
#include "comm.h"
#include "dihedral.h"
#include "domain.h"
#include "error.h"
#include "force.h"
@ -38,8 +39,10 @@
using namespace LAMMPS_NS;
#define SMALL 0.001
enum { X, Y, Z };
enum { TOTAL, CONF, KIN, PAIR, BOND, ANGLE };
enum { TOTAL, CONF, KIN, PAIR, BOND, ANGLE, DIHEDRAL };
/* ---------------------------------------------------------------------- */
@ -49,6 +52,7 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute(
bondflag = 0;
angleflag = 0;
dihedralflag = 0;
// set compute mode and direction of plane(s) for pressure calculation
@ -129,6 +133,11 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute(
which[nvalues] = ANGLE;
nvalues++;
}
} else if (strcmp(arg[iarg],"dihedral") == 0) {
for (i=0; i<3; i++) {
which[nvalues] = DIHEDRAL;
nvalues++;
}
} else
error->all(FLERR, "Illegal compute stress/mop command"); //break;
@ -152,6 +161,8 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute(
bond_global = nullptr;
angle_local = nullptr;
angle_global = nullptr;
dihedral_local = nullptr;
dihedral_global = nullptr;
// this fix produces a global vector
@ -162,6 +173,8 @@ ComputeStressMop::ComputeStressMop(LAMMPS *lmp, int narg, char **arg) : Compute(
memory->create(bond_global, nvalues, "stress/mop:bond_global");
memory->create(angle_local, nvalues, "stress/mop:angle_local");
memory->create(angle_global, nvalues, "stress/mop:angle_global");
memory->create(dihedral_local,nvalues,"stress/mop:dihedral_local");
memory->create(dihedral_global,nvalues,"stress/mop:dihedral_global");
size_vector = nvalues;
vector_flag = 1;
@ -180,6 +193,8 @@ ComputeStressMop::~ComputeStressMop()
memory->destroy(bond_global);
memory->destroy(angle_local);
memory->destroy(angle_global);
memory->destroy(dihedral_local);
memory->destroy(dihedral_global);
memory->destroy(vector);
}
@ -233,9 +248,13 @@ void ComputeStressMop::init()
}
}
if (force->dihedral) {
if ((strcmp(force->dihedral_style, "zero") != 0) &&
(strcmp(force->dihedral_style, "none") != 0))
error->all(FLERR, "compute stress/mop does not account for dihedral potentials");
if (force->dihedral->born_matrix_enable == 0) {
if ((strcmp(force->dihedral_style, "zero") != 0) &&
(strcmp(force->dihedral_style, "none") != 0))
error->all(FLERR, "compute stress/mop does not account for dihedral potentials");
} else {
dihedralflag = 1;
}
}
if (force->improper) {
if ((strcmp(force->improper_style, "zero") != 0) &&
@ -297,8 +316,18 @@ void ComputeStressMop::compute_vector()
MPI_Allreduce(angle_local, angle_global, nvalues, MPI_DOUBLE, MPI_SUM, world);
if (dihedralflag) {
//Compute dihedral contribution on separate procs
compute_dihedrals();
} else {
for (int i=0; i<nvalues; i++) dihedral_local[i] = 0.0;
}
// sum dihedral contribution over all procs
MPI_Allreduce(dihedral_local,dihedral_global,nvalues,MPI_DOUBLE,MPI_SUM,world);
for (int m = 0; m < nvalues; m++) {
vector[m] = values_global[m] + bond_global[m] + angle_global[m];
vector[m] = values_global[m] + bond_global[m] + angle_global[m] + dihedral_global[m];
}
}
@ -429,7 +458,12 @@ void ComputeStressMop::compute_pairs()
xi[1] = atom->x[i][1];
xi[2] = atom->x[i][2];
// velocities at t
// minimum image of xi with respect to the plane
xi[dir] -= pos;
domain->minimum_image(xi[0], xi[1], xi[2]);
xi[dir] += pos;
//velocities at t
vi[0] = atom->v[i][0];
vi[1] = atom->v[i][1];
@ -454,10 +488,8 @@ void ComputeStressMop::compute_pairs()
// at each timestep, must check atoms going through the
// image of the plane that is closest to the box
double pos_temp = pos + copysign(1.0, domain->prd_half[dir] - pos) * domain->prd[dir];
if (fabs(xi[dir] - pos) < fabs(xi[dir] - pos_temp)) pos_temp = pos;
if (((xi[dir] - pos_temp) * (xj[dir] - pos_temp)) < 0) {
double tau = (xi[dir] - pos) / (xi[dir] - xj[dir]);
if ((tau <= 1) && (tau >= 0)) {
// sgn = copysign(1.0,vi[dir]-vcm[dir]);
@ -786,3 +818,308 @@ void ComputeStressMop::compute_angles()
m += 3;
}
}
/*------------------------------------------------------------------------
compute dihedral contribution to pressure of local proc
-------------------------------------------------------------------------*/
void ComputeStressMop::compute_dihedrals()
{
int i, nd, atom1, atom2, atom3, atom4, imol, iatom;
tagint tagprev;
double vb1x, vb1y, vb1z, vb2x, vb2y, vb2z, vb3x, vb3y, vb3z;
double vb2xm, vb2ym, vb2zm;
double sb1, sb2, sb3, rb1, rb3, c0, b1mag2, b1mag, b2mag2;
double b2mag, b3mag2, b3mag, c2mag, ctmp, r12c1, c1mag, r12c2;
double s1, s2, s12, sc1, sc2, a11, a22, a33, a12, a13, a23;
double df[3], f1[3], f2[3], f3[3], f4[3];
double c, sx2, sy2, sz2, sin2;
double **x = atom->x;
tagint *tag = atom->tag;
int *num_dihedral = atom->num_dihedral;
tagint **dihedral_atom1 = atom->dihedral_atom1;
tagint **dihedral_atom2 = atom->dihedral_atom2;
tagint **dihedral_atom3 = atom->dihedral_atom3;
tagint **dihedral_atom4 = atom->dihedral_atom4;
int *mask = atom->mask;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int nlocal = atom->nlocal;
int molecular = atom->molecular;
// loop over all atoms and their dihedrals
Dihedral *dihedral = force->dihedral;
double dudih, du2dih;
double diffx[3] = {0.0, 0.0, 0.0};
double x_atom_1[3] = {0.0, 0.0, 0.0};
double x_atom_2[3] = {0.0, 0.0, 0.0};
double x_atom_3[3] = {0.0, 0.0, 0.0};
double x_atom_4[3] = {0.0, 0.0, 0.0};
// initialization
for (int i = 0; i < nvalues; i++) {
dihedral_local[i] = 0.0;
}
double local_contribution[3] = {0.0, 0.0, 0.0};
for (atom2 = 0; atom2 < nlocal; atom2++) {
if (!(mask[atom2] & groupbit)) continue;
if (molecular == Atom::MOLECULAR)
nd = num_dihedral[atom2];
else {
if (molindex[atom2] < 0) continue;
imol = molindex[atom2];
iatom = molatom[atom2];
nd = onemols[imol]->num_dihedral[iatom];
}
for (i = 0; i < nd; i++) {
if (molecular == 1) {
if (tag[atom2] != dihedral_atom2[atom2][i]) continue;
atom1 = atom->map(dihedral_atom1[atom2][i]);
atom3 = atom->map(dihedral_atom3[atom2][i]);
atom4 = atom->map(dihedral_atom4[atom2][i]);
} else {
if (tag[atom2] != onemols[imol]->dihedral_atom2[atom2][i]) continue;
tagprev = tag[atom2] - iatom - 1;
atom1 = atom->map(onemols[imol]->dihedral_atom1[atom2][i] + tagprev);
atom3 = atom->map(onemols[imol]->dihedral_atom3[atom2][i] + tagprev);
atom4 = atom->map(onemols[imol]->dihedral_atom4[atom2][i] + tagprev);
}
if (atom1 < 0 || !(mask[atom1] & groupbit)) continue;
if (atom3 < 0 || !(mask[atom3] & groupbit)) continue;
if (atom4 < 0 || !(mask[atom4] & groupbit)) continue;
// minimum image of atom1 with respect to the plane of interest
x_atom_1[0] = x[atom1][0];
x_atom_1[1] = x[atom1][1];
x_atom_1[2] = x[atom1][2];
x_atom_1[dir] -= pos;
domain->minimum_image(x_atom_1[0], x_atom_1[1], x_atom_1[2]);
x_atom_1[dir] += pos;
// minimum image of atom2 with respect to atom1
diffx[0] = x[atom2][0] - x_atom_1[0];
diffx[1] = x[atom2][1] - x_atom_1[1];
diffx[2] = x[atom2][2] - x_atom_1[2];
domain->minimum_image(diffx[0], diffx[1], diffx[2]);
x_atom_2[0] = x_atom_1[0] + diffx[0];
x_atom_2[1] = x_atom_1[1] + diffx[1];
x_atom_2[2] = x_atom_1[2] + diffx[2];
// minimum image of atom3 with respect to atom2
diffx[0] = x[atom3][0] - x_atom_2[0];
diffx[1] = x[atom3][1] - x_atom_2[1];
diffx[2] = x[atom3][2] - x_atom_2[2];
domain->minimum_image(diffx[0], diffx[1], diffx[2]);
x_atom_3[0] = x_atom_2[0] + diffx[0];
x_atom_3[1] = x_atom_2[1] + diffx[1];
x_atom_3[2] = x_atom_2[2] + diffx[2];
// minimum image of atom3 with respect to atom2
diffx[0] = x[atom4][0] - x_atom_3[0];
diffx[1] = x[atom4][1] - x_atom_3[1];
diffx[2] = x[atom4][2] - x_atom_3[2];
domain->minimum_image(diffx[0], diffx[1], diffx[2]);
x_atom_4[0] = x_atom_3[0] + diffx[0];
x_atom_4[1] = x_atom_3[1] + diffx[1];
x_atom_4[2] = x_atom_3[2] + diffx[2];
// check if any bond vector crosses the plane of interest
double tau_right = (x_atom_2[dir] - pos) / (x_atom_2[dir] - x_atom_1[dir]);
double tau_middle = (x_atom_3[dir] - pos) / (x_atom_3[dir] - x_atom_2[dir]);
double tau_left = (x_atom_4[dir] - pos) / (x_atom_4[dir] - x_atom_3[dir]);
bool right_cross = ((tau_right >=0) && (tau_right <= 1));
bool middle_cross = ((tau_middle >= 0) && (tau_middle <= 1));
bool left_cross = ((tau_left >=0) && (tau_left <= 1));
// no bonds crossing the plane
if (!right_cross && !middle_cross && !left_cross) continue;
dihedral->born_matrix(i, atom1, atom2, atom3, atom4, dudih, du2dih);
// first bond
vb1x = x_atom_1[0] - x_atom_2[0];
vb1y = x_atom_1[1] - x_atom_2[1];
vb1z = x_atom_1[2] - x_atom_2[2];
// second bond
vb2x = x_atom_3[0] - x_atom_2[0];
vb2y = x_atom_3[1] - x_atom_2[1];
vb2z = x_atom_3[2] - x_atom_2[2];
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
// third bond
vb3x = x_atom_4[0] - x_atom_3[0];
vb3y = x_atom_4[1] - x_atom_3[1];
vb3z = x_atom_4[2] - x_atom_3[2];
// c0 calculation
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - c1mag*c1mag,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - c2mag*c2mag,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
// error check
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// forces on each particle
double a = dudih;
c = c * a;
s12 = s12 * a;
a11 = c*sb1*s1;
a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = c*sb3*s2;
a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
a13 = -rb1*rb3*s12;
a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// only right bond crossing the plane
if (right_cross && !middle_cross && !left_cross)
{
double sgn = copysign(1.0, x_atom_1[dir] - pos);
df[0] = sgn * f1[0];
df[1] = sgn * f1[1];
df[2] = sgn * f1[2];
}
// only middle bond crossing the plane
if (!right_cross && middle_cross && !left_cross)
{
double sgn = copysign(1.0, x_atom_2[dir] - pos);
df[0] = sgn * (f2[0] + f1[0]);
df[1] = sgn * (f2[1] + f1[1]);
df[2] = sgn * (f2[2] + f1[2]);
}
// only left bond crossing the plane
if (!right_cross && !middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_4[dir] - pos);
df[0] = sgn * f4[0];
df[1] = sgn * f4[1];
df[2] = sgn * f4[2];
}
// only right & middle bonds crossing the plane
if (right_cross && middle_cross && !left_cross)
{
double sgn = copysign(1.0, x_atom_2[dir] - pos);
df[0] = sgn * f2[0];
df[1] = sgn * f2[1];
df[2] = sgn * f2[2];
}
// only right & left bonds crossing the plane
if (right_cross && !middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_1[dir] - pos);
df[0] = sgn * (f1[0] + f4[0]);
df[1] = sgn * (f1[1] + f4[1]);
df[2] = sgn * (f1[2] + f4[2]);
}
// only middle & left bonds crossing the plane
if (!right_cross && middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_3[dir] - pos);
df[0] = sgn * f3[0];
df[1] = sgn * f3[1];
df[2] = sgn * f3[2];
}
// all three bonds crossing the plane
if (right_cross && middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_1[dir] - pos);
df[0] = sgn * (f1[0] + f3[0]);
df[1] = sgn * (f1[1] + f3[1]);
df[2] = sgn * (f1[2] + f3[2]);
}
local_contribution[0] += df[0]/area*nktv2p;
local_contribution[1] += df[1]/area*nktv2p;
local_contribution[2] += df[2]/area*nktv2p;
}
}
// loop over the keywords and if necessary add the dihedral contribution
int m = 0;
while (m < nvalues) {
if ((which[m] == CONF) || (which[m] == TOTAL) || (which[m] == DIHEDRAL)) {
dihedral_local[m] = local_contribution[0];
dihedral_local[m+1] = local_contribution[1];
dihedral_local[m+2] = local_contribution[2];
}
m += 3;
}
}

View File

@ -40,15 +40,17 @@ class ComputeStressMop : public Compute {
void compute_pairs();
void compute_bonds();
void compute_angles();
void compute_dihedrals();
int nvalues, dir;
int *which;
int bondflag, angleflag;
int bondflag, angleflag, dihedralflag;
double *values_local, *values_global;
double *bond_local, *bond_global;
double *angle_local, *angle_global;
double *dihedral_local, *dihedral_global;
double pos, pos1, dt, nktv2p, ftm2v;
double area;
class NeighList *list;

View File

@ -13,15 +13,17 @@
/*------------------------------------------------------------------------
Contributing Authors : Romain Vermorel (LFCR), Laurent Joly (ULyon)
Support for bonds added by : Evangelos Voyiatzis (NovaMechanics)
Support for bonds, angles and dihedrals added by : Evangelos Voyiatzis (NovaMechanics)
--------------------------------------------------------------------------*/
#include "compute_stress_mop_profile.h"
#include "angle.h"
#include "atom.h"
#include "atom_vec.h"
#include "bond.h"
#include "comm.h"
#include "dihedral.h"
#include "domain.h"
#include "error.h"
#include "force.h"
@ -37,9 +39,10 @@
using namespace LAMMPS_NS;
#define SMALL 0.001
enum { X, Y, Z };
enum { LOWER, CENTER, UPPER, COORD };
enum { TOTAL, CONF, KIN, PAIR, BOND };
enum { TOTAL, CONF, KIN, PAIR, BOND, ANGLE, DIHEDRAL };
/* ---------------------------------------------------------------------- */
@ -49,6 +52,8 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a
if (narg < 7) utils::missing_cmd_args(FLERR, "compute stress/mop/profile", error);
bondflag = 0;
angleflag = 0;
dihedralflag = 0;
// set compute mode and direction of plane(s) for pressure calculation
@ -63,15 +68,15 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a
// bin parameters
if (strcmp(arg[4], "lower") == 0)
originflag = LOWER;
else if (strcmp(arg[4], "center") == 0)
originflag = CENTER;
else if (strcmp(arg[4], "upper") == 0)
originflag = UPPER;
else
originflag = COORD;
if (originflag == COORD) origin = utils::numeric(FLERR, arg[4], false, lmp);
if (strcmp(arg[4], "lower") == 0) {
origin = domain->boxlo[dir];
} else if (strcmp(arg[4], "center") == 0) {
origin = 0.5 * (domain->boxlo[dir] + domain->boxhi[dir]);
} else if (strcmp(arg[4], "upper") == 0) {
origin = domain->boxhi[dir];
} else {
origin = utils::numeric(FLERR, arg[4], false, lmp);
}
delta = utils::numeric(FLERR, arg[5], false, lmp);
invdelta = 1.0 / delta;
@ -108,6 +113,16 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a
which[nvalues] = BOND;
nvalues++;
}
} else if (strcmp(arg[iarg], "angle") == 0) {
for (i = 0; i < 3; i++) {
which[nvalues] = ANGLE;
nvalues++;
}
} else if (strcmp(arg[iarg],"dihedral") == 0) {
for (i=0; i<3; i++) {
which[nvalues] = DIHEDRAL;
nvalues++;
}
} else
error->all(FLERR, "Illegal compute stress/mop/profile command"); //break;
@ -133,6 +148,10 @@ ComputeStressMopProfile::ComputeStressMopProfile(LAMMPS *lmp, int narg, char **a
values_local = values_global = array = nullptr;
bond_local = nullptr;
bond_global = nullptr;
angle_local = nullptr;
angle_global = nullptr;
dihedral_local = nullptr;
dihedral_global = nullptr;
local_contribution = nullptr;
// bin setup
@ -161,6 +180,10 @@ ComputeStressMopProfile::~ComputeStressMopProfile()
memory->destroy(values_global);
memory->destroy(bond_local);
memory->destroy(bond_global);
memory->destroy(angle_local);
memory->destroy(angle_global);
memory->destroy(dihedral_local);
memory->destroy(dihedral_global);
memory->destroy(local_contribution);
memory->destroy(array);
}
@ -208,13 +231,25 @@ void ComputeStressMopProfile::init()
if (force->bond) bondflag = 1;
if (force->angle)
if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0))
error->all(FLERR, "compute stress/mop/profile does not account for angle potentials");
if (force->dihedral)
if ((strcmp(force->dihedral_style, "zero") != 0) &&
(strcmp(force->dihedral_style, "none") != 0))
error->all(FLERR, "compute stress/mop/profile does not account for dihedral potentials");
if (force->angle) {
if (force->angle->born_matrix_enable == 0) {
if ((strcmp(force->angle_style, "zero") != 0) && (strcmp(force->angle_style, "none") != 0))
error->all(FLERR,"compute stress/mop/profile does not account for angle potentials");
} else {
angleflag = 1;
}
}
if (force->dihedral) {
if (force->dihedral->born_matrix_enable == 0) {
if ((strcmp(force->dihedral_style, "zero") != 0) &&
(strcmp(force->dihedral_style, "none") != 0))
error->all(FLERR, "compute stress/mop/profile does not account for dihedral potentials");
} else {
dihedralflag = 1;
}
}
if (force->improper)
if ((strcmp(force->improper_style, "zero") != 0) &&
(strcmp(force->improper_style, "none") != 0))
@ -263,16 +298,43 @@ void ComputeStressMopProfile::compute_array()
}
// sum bond contribution over all procs
MPI_Allreduce(&bond_local[0][0], &bond_global[0][0], nbins * nvalues, MPI_DOUBLE, MPI_SUM, world);
if (angleflag) {
//Compute angle contribution on separate procs
compute_angles();
} else {
for (int m = 0; m < nbins; m++) {
for (int i = 0; i < nvalues; i++) {
angle_local[m][i] = 0.0;
}
}
}
// sum angle contribution over all procs
MPI_Allreduce(&angle_local[0][0],&angle_global[0][0],nbins*nvalues,MPI_DOUBLE,MPI_SUM,world);
if (dihedralflag) {
//Compute dihedral contribution on separate procs
compute_dihedrals();
} else {
for (int m = 0; m < nbins; m++) {
for (int i = 0; i < nvalues; i++) {
dihedral_local[m][i] = 0.0;
}
}
}
// sum dihedral contribution over all procs
MPI_Allreduce(&dihedral_local[0][0],&dihedral_global[0][0],nbins*nvalues,MPI_DOUBLE,MPI_SUM,world);
for (int ibin = 0; ibin < nbins; ibin++) {
array[ibin][0] = coord[ibin][0];
array[ibin][0] = coord[ibin];
int mo = 1;
int m = 0;
while (m < nvalues) {
array[ibin][m + mo] = values_global[ibin][m] + bond_global[ibin][m];
array[ibin][m + mo] = values_global[ibin][m] + bond_global[ibin][m] + angle_global[ibin][m] + dihedral_global[ibin][m];
m++;
}
}
@ -366,8 +428,8 @@ void ComputeStressMopProfile::compute_pairs()
if (newton_pair || j < nlocal) {
for (ibin = 0; ibin < nbins; ibin++) {
pos = coord[ibin][0];
pos1 = coordp[ibin][0];
pos = coord[ibin];
pos1 = coordp[ibin];
// check if ij pair is across plane, add contribution to pressure
@ -392,8 +454,8 @@ void ComputeStressMopProfile::compute_pairs()
} else {
for (ibin = 0; ibin < nbins; ibin++) {
pos = coord[ibin][0];
pos1 = coordp[ibin][0];
pos = coord[ibin];
pos1 = coordp[ibin];
//check if ij pair is across plane, add contribution to pressure
@ -454,15 +516,29 @@ void ComputeStressMopProfile::compute_pairs()
xj[2] = xi[2] - vi[2] * dt + fi[2] * iterm * dt;
for (ibin = 0; ibin < nbins; ibin++) {
pos = coord[ibin][0];
pos1 = coordp[ibin][0];
pos = coord[ibin];
pos1 = coordp[ibin];
if (((xi[dir] - pos) * (xj[dir] - pos) * (xi[dir] - pos1) * (xj[dir] - pos1) < 0)) {
// minimum image of xi with respect to the plane
xi[dir] -= pos;
domain->minimum_image(xi[0], xi[1], xi[2]);
xi[dir] += pos;
// minimum image of xj with respect to xi
xj[0] -= xi[0];
xj[1] -= xi[1];
xj[2] -= xi[2];
domain->minimum_image(xi[0], xi[1], xi[2]);
xj[0] += xi[0];
xj[1] += xi[1];
xj[2] += xi[2];
double tau = (xi[dir] - pos) / (xi[dir] - xj[dir]);
if ((tau <= 1) && (tau >= 0)) {
sgn = copysign(1.0, vi[dir]);
// approximate crossing velocity by v(t-dt/2) (based on Velocity-Verlet alg.)
//approximate crossing velocity by v(t-dt/2) (based on Velocity-Verlet alg.)
double vcross[3];
vcross[0] = vi[0] - fi[0] * iterm;
vcross[1] = vi[1] - fi[1] * iterm;
@ -549,7 +625,7 @@ void ComputeStressMopProfile::compute_bonds()
if (btype <= 0) continue;
for (int ibin = 0; ibin < nbins; ibin++) {
double pos = coord[ibin][0];
double pos = coord[ibin];
// minimum image of atom1 with respect to the plane of interest
@ -607,6 +683,506 @@ void ComputeStressMopProfile::compute_bonds()
}
}
/*------------------------------------------------------------------------
compute angle contribution to pressure of local proc
-------------------------------------------------------------------------*/
void ComputeStressMopProfile::compute_angles()
{
int na, atom1, atom2, atom3, imol, iatom, atype;
tagint tagprev;
double r1, r2, cos_theta;
double **x = atom->x;
tagint *tag = atom->tag;
int *num_angle = atom->num_angle;
tagint **angle_atom1 = atom->angle_atom1;
tagint **angle_atom2 = atom->angle_atom2;
tagint **angle_atom3 = atom->angle_atom3;
int **angle_type = atom->angle_type;
int *mask = atom->mask;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int nlocal = atom->nlocal;
int molecular = atom->molecular;
// loop over all atoms and their angles
Angle *angle = force->angle;
double duang, du2ang;
double dx[3] = {0.0, 0.0, 0.0};
double dx_left[3] = {0.0, 0.0, 0.0};
double dx_right[3] = {0.0, 0.0, 0.0};
double x_angle_left[3] = {0.0, 0.0, 0.0};
double x_angle_middle[3] = {0.0, 0.0, 0.0};
double x_angle_right[3] = {0.0, 0.0, 0.0};
double dcos_theta[3] = {0.0, 0.0, 0.0};
// initialization
for (int m = 0; m < nbins; m++) {
for (int i = 0; i < nvalues; i++) {
angle_local[m][i] = 0.0;
}
local_contribution[m][0] = 0.0;
local_contribution[m][1] = 0.0;
local_contribution[m][2] = 0.0;
}
for (atom2 = 0; atom2 < nlocal; atom2++) {
if (!(mask[atom2] & groupbit)) continue;
if (molecular == 1)
na = num_angle[atom2];
else {
if (molindex[atom2] < 0) continue;
imol = molindex[atom2];
iatom = molatom[atom2];
na = onemols[imol]->num_angle[iatom];
}
for (int i = 0; i < na; i++) {
if (molecular == 1) {
if (tag[atom2] != angle_atom2[atom2][i]) continue;
atype = angle_type[atom2][i];
atom1 = atom->map(angle_atom1[atom2][i]);
atom3 = atom->map(angle_atom3[atom2][i]);
} else {
if (tag[atom2] != onemols[imol]->angle_atom2[atom2][i]) continue;
atype = onemols[imol]->angle_type[atom2][i];
tagprev = tag[atom2] - iatom - 1;
atom1 = atom->map(onemols[imol]->angle_atom1[atom2][i] + tagprev);
atom3 = atom->map(onemols[imol]->angle_atom3[atom2][i] + tagprev);
}
if (atom1 < 0 || !(mask[atom1] & groupbit)) continue;
if (atom3 < 0 || !(mask[atom3] & groupbit)) continue;
if (atype <= 0) continue;
for (int ibin = 0; ibin<nbins; ibin++) {
double pos = coord[ibin];
// minimum image of atom1 with respect to the plane of interest
dx[0] = x[atom1][0];
dx[1] = x[atom1][1];
dx[2] = x[atom1][2];
dx[dir] -= pos;
domain->minimum_image(dx[0], dx[1], dx[2]);
x_angle_left[0] = dx[0];
x_angle_left[1] = dx[1];
x_angle_left[2] = dx[2];
x_angle_left[dir] += pos;
// minimum image of atom2 with respect to atom1
dx_left[0] = x[atom2][0] - x_angle_left[0];
dx_left[1] = x[atom2][1] - x_angle_left[1];
dx_left[2] = x[atom2][2] - x_angle_left[2];
domain->minimum_image(dx_left[0], dx_left[1], dx_left[2]);
x_angle_middle[0] = x_angle_left[0] + dx_left[0];
x_angle_middle[1] = x_angle_left[1] + dx_left[1];
x_angle_middle[2] = x_angle_left[2] + dx_left[2];
// minimum image of atom3 with respect to atom2
dx_right[0] = x[atom3][0] - x_angle_middle[0];
dx_right[1] = x[atom3][1] - x_angle_middle[1];
dx_right[2] = x[atom3][2] - x_angle_middle[2];
domain->minimum_image(dx_right[0], dx_right[1], dx_right[2]);
x_angle_right[0] = x_angle_middle[0] + dx_right[0];
x_angle_right[1] = x_angle_middle[1] + dx_right[1];
x_angle_right[2] = x_angle_middle[2] + dx_right[2];
// check if any bond vector crosses the plane of interest
double tau_right = (x_angle_right[dir] - pos) / (x_angle_right[dir] - x_angle_middle[dir]);
double tau_left = (x_angle_middle[dir] - pos) / (x_angle_middle[dir] - x_angle_left[dir]);
bool right_cross = ((tau_right >=0) && (tau_right <= 1));
bool left_cross = ((tau_left >=0) && (tau_left <= 1));
// no bonds crossing the plane
if (!right_cross && !left_cross) continue;
// compute the cos(theta) of the angle
r1 = sqrt(dx_left[0]*dx_left[0] + dx_left[1]*dx_left[1] + dx_left[2]*dx_left[2]);
r2 = sqrt(dx_right[0]*dx_right[0] + dx_right[1]*dx_right[1] + dx_right[2]*dx_right[2]);
cos_theta = -(dx_right[0]*dx_left[0] + dx_right[1]*dx_left[1] + dx_right[2]*dx_left[2])/(r1*r2);
if (cos_theta > 1.0) cos_theta = 1.0;
if (cos_theta < -1.0) cos_theta = -1.0;
// The method returns derivative with regards to cos(theta)
angle->born_matrix(atype, atom1, atom2, atom3, duang, du2ang);
// only right bond crossing the plane
if (right_cross && !left_cross)
{
double sgn = copysign(1.0, x_angle_right[dir] - pos);
dcos_theta[0] = sgn*(dx_right[0]*cos_theta/r2 + dx_left[0]/r1)/r2;
dcos_theta[1] = sgn*(dx_right[1]*cos_theta/r2 + dx_left[1]/r1)/r2;
dcos_theta[2] = sgn*(dx_right[2]*cos_theta/r2 + dx_left[2]/r1)/r2;
}
// only left bond crossing the plane
if (!right_cross && left_cross)
{
double sgn = copysign(1.0, x_angle_left[dir] - pos);
dcos_theta[0] = -sgn*(dx_left[0]*cos_theta/r1 + dx_right[0]/r2)/r1;
dcos_theta[1] = -sgn*(dx_left[1]*cos_theta/r1 + dx_right[1]/r2)/r1;
dcos_theta[2] = -sgn*(dx_left[2]*cos_theta/r1 + dx_right[2]/r2)/r1;
}
// both bonds crossing the plane
if (right_cross && left_cross)
{
// due to right bond
double sgn = copysign(1.0, x_angle_middle[dir] - pos);
dcos_theta[0] = -sgn*(dx_right[0]*cos_theta/r2 + dx_left[0]/r1)/r2;
dcos_theta[1] = -sgn*(dx_right[1]*cos_theta/r2 + dx_left[1]/r1)/r2;
dcos_theta[2] = -sgn*(dx_right[2]*cos_theta/r2 + dx_left[2]/r1)/r2;
// due to left bond
dcos_theta[0] += sgn*(dx_left[0]*cos_theta/r1 + dx_right[0]/r2)/r1;
dcos_theta[1] += sgn*(dx_left[1]*cos_theta/r1 + dx_right[1]/r2)/r1;
dcos_theta[2] += sgn*(dx_left[2]*cos_theta/r1 + dx_right[2]/r2)/r1;
}
// final contribution of the given angle term
local_contribution[ibin][0] += duang*dcos_theta[0]/area*nktv2p;
local_contribution[ibin][1] += duang*dcos_theta[1]/area*nktv2p;
local_contribution[ibin][2] += duang*dcos_theta[2]/area*nktv2p;
}
}
}
// loop over the keywords and if necessary add the angle contribution
int m = 0;
while (m < nvalues) {
if (which[m] == CONF || which[m] == TOTAL || which[m] == ANGLE) {
for (int ibin = 0; ibin < nbins; ibin++) {
angle_local[ibin][m] = local_contribution[ibin][0];
angle_local[ibin][m+1] = local_contribution[ibin][1];
angle_local[ibin][m+2] = local_contribution[ibin][2];
}
}
m += 3;
}
}
/*------------------------------------------------------------------------
compute dihedral contribution to pressure of local proc
-------------------------------------------------------------------------*/
void ComputeStressMopProfile::compute_dihedrals()
{
int i, nd, atom1, atom2, atom3, atom4, imol, iatom;
tagint tagprev;
double vb1x, vb1y, vb1z, vb2x, vb2y, vb2z, vb3x, vb3y, vb3z;
double vb2xm, vb2ym, vb2zm;
double sb1, sb2, sb3, rb1, rb3, c0, b1mag2, b1mag, b2mag2;
double b2mag, b3mag2, b3mag, c2mag, ctmp, r12c1, c1mag, r12c2;
double s1, s2, s12, sc1, sc2, a11, a22, a33, a12, a13, a23;
double df[3], f1[3], f2[3], f3[3], f4[3];
double c, sx2, sy2, sz2, sin2;
double **x = atom->x;
tagint *tag = atom->tag;
int *num_dihedral = atom->num_dihedral;
tagint **dihedral_atom1 = atom->dihedral_atom1;
tagint **dihedral_atom2 = atom->dihedral_atom2;
tagint **dihedral_atom3 = atom->dihedral_atom3;
tagint **dihedral_atom4 = atom->dihedral_atom4;
int *mask = atom->mask;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int nlocal = atom->nlocal;
int molecular = atom->molecular;
// loop over all atoms and their dihedrals
Dihedral *dihedral = force->dihedral;
double dudih, du2dih;
double diffx[3] = {0.0, 0.0, 0.0};
double x_atom_1[3] = {0.0, 0.0, 0.0};
double x_atom_2[3] = {0.0, 0.0, 0.0};
double x_atom_3[3] = {0.0, 0.0, 0.0};
double x_atom_4[3] = {0.0, 0.0, 0.0};
// initialization
for (int m = 0; m < nbins; m++) {
for (int i = 0; i < nvalues; i++) {
dihedral_local[m][i] = 0.0;
}
local_contribution[m][0] = 0.0;
local_contribution[m][1] = 0.0;
local_contribution[m][2] = 0.0;
}
for (atom2 = 0; atom2 < nlocal; atom2++) {
if (!(mask[atom2] & groupbit)) continue;
if (molecular == Atom::MOLECULAR)
nd = num_dihedral[atom2];
else {
if (molindex[atom2] < 0) continue;
imol = molindex[atom2];
iatom = molatom[atom2];
nd = onemols[imol]->num_dihedral[iatom];
}
for (i = 0; i < nd; i++) {
if (molecular == 1) {
if (tag[atom2] != dihedral_atom2[atom2][i]) continue;
atom1 = atom->map(dihedral_atom1[atom2][i]);
atom3 = atom->map(dihedral_atom3[atom2][i]);
atom4 = atom->map(dihedral_atom4[atom2][i]);
} else {
if (tag[atom2] != onemols[imol]->dihedral_atom2[atom2][i]) continue;
tagprev = tag[atom2] - iatom - 1;
atom1 = atom->map(onemols[imol]->dihedral_atom1[atom2][i] + tagprev);
atom3 = atom->map(onemols[imol]->dihedral_atom3[atom2][i] + tagprev);
atom4 = atom->map(onemols[imol]->dihedral_atom4[atom2][i] + tagprev);
}
if (atom1 < 0 || !(mask[atom1] & groupbit)) continue;
if (atom3 < 0 || !(mask[atom3] & groupbit)) continue;
if (atom4 < 0 || !(mask[atom4] & groupbit)) continue;
for (int ibin = 0; ibin<nbins; ibin++) {
double pos = coord[ibin];
// minimum image of atom1 with respect to the plane of interest
x_atom_1[0] = x[atom1][0];
x_atom_1[1] = x[atom1][1];
x_atom_1[2] = x[atom1][2];
x_atom_1[dir] -= pos;
domain->minimum_image(x_atom_1[0], x_atom_1[1], x_atom_1[2]);
x_atom_1[dir] += pos;
// minimum image of atom2 with respect to atom1
diffx[0] = x[atom2][0] - x_atom_1[0];
diffx[1] = x[atom2][1] - x_atom_1[1];
diffx[2] = x[atom2][2] - x_atom_1[2];
domain->minimum_image(diffx[0], diffx[1], diffx[2]);
x_atom_2[0] = x_atom_1[0] + diffx[0];
x_atom_2[1] = x_atom_1[1] + diffx[1];
x_atom_2[2] = x_atom_1[2] + diffx[2];
// minimum image of atom3 with respect to atom2
diffx[0] = x[atom3][0] - x_atom_2[0];
diffx[1] = x[atom3][1] - x_atom_2[1];
diffx[2] = x[atom3][2] - x_atom_2[2];
domain->minimum_image(diffx[0], diffx[1], diffx[2]);
x_atom_3[0] = x_atom_2[0] + diffx[0];
x_atom_3[1] = x_atom_2[1] + diffx[1];
x_atom_3[2] = x_atom_2[2] + diffx[2];
// minimum image of atom3 with respect to atom2
diffx[0] = x[atom4][0] - x_atom_3[0];
diffx[1] = x[atom4][1] - x_atom_3[1];
diffx[2] = x[atom4][2] - x_atom_3[2];
domain->minimum_image(diffx[0], diffx[1], diffx[2]);
x_atom_4[0] = x_atom_3[0] + diffx[0];
x_atom_4[1] = x_atom_3[1] + diffx[1];
x_atom_4[2] = x_atom_3[2] + diffx[2];
// check if any bond vector crosses the plane of interest
double tau_right = (x_atom_2[dir] - pos) / (x_atom_2[dir] - x_atom_1[dir]);
double tau_middle = (x_atom_3[dir] - pos) / (x_atom_3[dir] - x_atom_2[dir]);
double tau_left = (x_atom_4[dir] - pos) / (x_atom_4[dir] - x_atom_3[dir]);
bool right_cross = ((tau_right >=0) && (tau_right <= 1));
bool middle_cross = ((tau_middle >= 0) && (tau_middle <= 1));
bool left_cross = ((tau_left >=0) && (tau_left <= 1));
// no bonds crossing the plane
if (!right_cross && !middle_cross && !left_cross) continue;
dihedral->born_matrix(i, atom1, atom2, atom3, atom4, dudih, du2dih);
// first bond
vb1x = x_atom_1[0] - x_atom_2[0];
vb1y = x_atom_1[1] - x_atom_2[1];
vb1z = x_atom_1[2] - x_atom_2[2];
// second bond
vb2x = x_atom_3[0] - x_atom_2[0];
vb2y = x_atom_3[1] - x_atom_2[1];
vb2z = x_atom_3[2] - x_atom_2[2];
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
// third bond
vb3x = x_atom_4[0] - x_atom_3[0];
vb3y = x_atom_4[1] - x_atom_3[1];
vb3z = x_atom_4[2] - x_atom_3[2];
// c0 calculation
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb2 = 1.0 / (vb2x*vb2x + vb2y*vb2y + vb2z*vb2z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - c1mag*c1mag,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - c2mag*c2mag,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
// error check
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
// forces on each particle
double a = dudih;
c = c * a;
s12 = s12 * a;
a11 = c*sb1*s1;
a22 = -sb2 * (2.0*c0*s12 - c*(s1+s2));
a33 = c*sb3*s2;
a12 = -r12c1 * (c1mag*c*s1 + c2mag*s12);
a13 = -rb1*rb3*s12;
a23 = r12c2 * (c2mag*c*s2 + c1mag*s12);
sx2 = a12*vb1x + a22*vb2x + a23*vb3x;
sy2 = a12*vb1y + a22*vb2y + a23*vb3y;
sz2 = a12*vb1z + a22*vb2z + a23*vb3z;
f1[0] = a11*vb1x + a12*vb2x + a13*vb3x;
f1[1] = a11*vb1y + a12*vb2y + a13*vb3y;
f1[2] = a11*vb1z + a12*vb2z + a13*vb3z;
f2[0] = -sx2 - f1[0];
f2[1] = -sy2 - f1[1];
f2[2] = -sz2 - f1[2];
f4[0] = a13*vb1x + a23*vb2x + a33*vb3x;
f4[1] = a13*vb1y + a23*vb2y + a33*vb3y;
f4[2] = a13*vb1z + a23*vb2z + a33*vb3z;
f3[0] = sx2 - f4[0];
f3[1] = sy2 - f4[1];
f3[2] = sz2 - f4[2];
// only right bond crossing the plane
if (right_cross && !middle_cross && !left_cross)
{
double sgn = copysign(1.0, x_atom_1[dir] - pos);
df[0] = sgn * f1[0];
df[1] = sgn * f1[1];
df[2] = sgn * f1[2];
}
// only middle bond crossing the plane
if (!right_cross && middle_cross && !left_cross)
{
double sgn = copysign(1.0, x_atom_2[dir] - pos);
df[0] = sgn * (f2[0] + f1[0]);
df[1] = sgn * (f2[1] + f1[1]);
df[2] = sgn * (f2[2] + f1[2]);
}
// only left bond crossing the plane
if (!right_cross && !middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_4[dir] - pos);
df[0] = sgn * f4[0];
df[1] = sgn * f4[1];
df[2] = sgn * f4[2];
}
// only right & middle bonds crossing the plane
if (right_cross && middle_cross && !left_cross)
{
double sgn = copysign(1.0, x_atom_2[dir] - pos);
df[0] = sgn * f2[0];
df[1] = sgn * f2[1];
df[2] = sgn * f2[2];
}
// only right & left bonds crossing the plane
if (right_cross && !middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_1[dir] - pos);
df[0] = sgn * (f1[0] + f4[0]);
df[1] = sgn * (f1[1] + f4[1]);
df[2] = sgn * (f1[2] + f4[2]);
}
// only middle & left bonds crossing the plane
if (!right_cross && middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_3[dir] - pos);
df[0] = sgn * f3[0];
df[1] = sgn * f3[1];
df[2] = sgn * f3[2];
}
// all three bonds crossing the plane
if (right_cross && middle_cross && left_cross)
{
double sgn = copysign(1.0, x_atom_1[dir] - pos);
df[0] = sgn * (f1[0] + f3[0]);
df[1] = sgn * (f1[1] + f3[1]);
df[2] = sgn * (f1[2] + f3[2]);
}
local_contribution[ibin][0] += df[0]/area*nktv2p;
local_contribution[ibin][1] += df[1]/area*nktv2p;
local_contribution[ibin][2] += df[2]/area*nktv2p;
}
}
}
// loop over the keywords and if necessary add the dihedral contribution
int m = 0;
while (m < nvalues) {
if ((which[m] == CONF) || (which[m] == TOTAL) || (which[m] == DIHEDRAL)) {
for (int ibin = 0; ibin < nbins; ibin++) {
dihedral_local[ibin][m] = local_contribution[ibin][0];
dihedral_local[ibin][m+1] = local_contribution[ibin][1];
dihedral_local[ibin][m+2] = local_contribution[ibin][2];
}
}
m += 3;
}
}
/* ----------------------------------------------------------------------
setup 1d bins and their extent and coordinates
called at init()
@ -621,47 +1197,39 @@ void ComputeStressMopProfile::setup_bins()
boxlo = domain->boxlo;
boxhi = domain->boxhi;
if (originflag == LOWER)
origin = boxlo[dir];
else if (originflag == UPPER)
origin = boxhi[dir];
else if (originflag == CENTER)
origin = 0.5 * (boxlo[dir] + boxhi[dir]);
if ((origin > domain->boxhi[dir]) || (origin < domain->boxlo[dir]))
error->all(FLERR, "Origin of bins for compute stress/mop/profile is out of bounds");
if (origin < boxlo[dir]) {
error->all(FLERR, "Origin of bins for compute stress/mop/profile is out of bounds");
} else {
n = static_cast<int>((origin - boxlo[dir]) * invdelta);
lo = origin - n * delta;
}
if (origin < boxhi[dir]) {
n = static_cast<int>((boxhi[dir] - origin) * invdelta);
hi = origin + n * delta;
} else {
error->all(FLERR, "Origin of bins for compute stress/mop/profile is out of bounds");
}
n = static_cast<int> ((origin - boxlo[dir]) * invdelta);
lo = origin - n*delta;
n = static_cast<int> ((boxhi[dir] - origin) * invdelta);
hi = origin + n*delta;
offset = lo;
nbins = static_cast<int>((hi - lo) * invdelta + 1.5);
// allocate bin arrays
memory->create(coord, nbins, 1, "stress/mop/profile:coord");
memory->create(coordp, nbins, 1, "stress/mop/profile:coordp");
//allocate bin arrays
memory->create(coord, nbins, "stress/mop/profile:coord");
memory->create(coordp, nbins, "stress/mop/profile:coordp");
memory->create(values_local, nbins, nvalues, "stress/mop/profile:values_local");
memory->create(values_global, nbins, nvalues, "stress/mop/profile:values_global");
memory->create(bond_local, nbins, nvalues, "stress/mop/profile:bond_local");
memory->create(bond_global, nbins, nvalues, "stress/mop/profile:bond_global");
memory->create(angle_local, nbins, nvalues, "stress/mop/profile:angle_local");
memory->create(angle_global, nbins, nvalues, "stress/mop/profile:angle_global");
memory->create(dihedral_local,nbins,nvalues,"stress/mop/profile:dihedral_local");
memory->create(dihedral_global,nbins,nvalues,"stress/mop/profile:dihedral_global");
memory->create(local_contribution, nbins, 3, "stress/mop/profile:local_contribution");
// set bin coordinates
for (i = 0; i < nbins; i++) {
coord[i][0] = offset + i * delta;
if (coord[i][0] < (domain->boxlo[dir] + domain->prd_half[dir])) {
coordp[i][0] = coord[i][0] + domain->prd[dir];
coord[i] = offset + i * delta;
if (coord[i] < (domain->boxlo[dir] + domain->prd_half[dir])) {
coordp[i] = coord[i] + domain->prd[dir];
} else {
coordp[i][0] = coord[i][0] - domain->prd[dir];
coordp[i] = coord[i] - domain->prd[dir];
}
}
}

View File

@ -39,19 +39,22 @@ class ComputeStressMopProfile : public Compute {
private:
void compute_pairs();
void compute_bonds();
void compute_angles();
void compute_dihedrals();
void setup_bins();
int nvalues, dir;
int *which;
int bondflag;
int bondflag, angleflag, dihedralflag;
int originflag;
double origin, delta, offset, invdelta;
int nbins;
double **coord, **coordp;
double *coord, *coordp;
double **values_local, **values_global;
double **bond_local, **bond_global;
double **angle_local, **angle_global;
double **dihedral_local, **dihedral_global;
double **local_contribution;
double dt, nktv2p, ftm2v;

View File

@ -38,7 +38,10 @@ using namespace MathSpecial;
/* ---------------------------------------------------------------------- */
AngleCosinePeriodic::AngleCosinePeriodic(LAMMPS *lmp) : Angle(lmp) {}
AngleCosinePeriodic::AngleCosinePeriodic(LAMMPS *lmp) : Angle(lmp)
{
born_matrix_enable = 1;
}
/* ---------------------------------------------------------------------- */
@ -298,3 +301,38 @@ double AngleCosinePeriodic::single(int type, int i1, int i2, int i3)
c = cos(acos(c)*multiplicity[type]);
return 2.0*k[type]*(1.0-b[type]*powsign(multiplicity[type])*c);
}
/* ---------------------------------------------------------------------- */
void AngleCosinePeriodic::born_matrix(int type, int i1, int i2, int i3, double &du, double &du2)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double theta = acos(c);
double s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
s = 1.0/s;
double m_angle = multiplicity[type] * theta;
double prefactor = -2.0 * k[type] * b[type] * powsign(multiplicity[type]) * multiplicity[type];
du = prefactor * sin(m_angle) / s;
du2 = prefactor * (c * sin(m_angle) - s * cos(m_angle) * multiplicity[type]) / (s * s * s);
}

View File

@ -35,6 +35,7 @@ class AngleCosinePeriodic : public Angle {
void read_restart(FILE *) override;
void write_data(FILE *) override;
double single(int, int, int, int) override;
void born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) override;
protected:
double *k;

View File

@ -39,6 +39,7 @@ using namespace MathConst;
AngleFourier::AngleFourier(LAMMPS *lmp) : Angle(lmp)
{
born_matrix_enable = 1;
k = nullptr;
C0 = nullptr;
C1 = nullptr;

View File

@ -37,7 +37,10 @@ using namespace MathConst;
/* ---------------------------------------------------------------------- */
AngleQuartic::AngleQuartic(LAMMPS *lmp) : Angle(lmp) {}
AngleQuartic::AngleQuartic(LAMMPS *lmp) : Angle(lmp)
{
born_matrix_enable = 1;
}
/* ---------------------------------------------------------------------- */
@ -286,3 +289,39 @@ double AngleQuartic::single(int type, int i1, int i2, int i3)
double dtheta4 = dtheta3 * dtheta;
return k2[type] * dtheta2 + k3[type] * dtheta3 + k4[type] * dtheta4;
}
/* ---------------------------------------------------------------------- */
void AngleQuartic::born_matrix(int type, int i1, int i2, int i3, double &du, double &du2)
{
double **x = atom->x;
double delx1 = x[i1][0] - x[i2][0];
double dely1 = x[i1][1] - x[i2][1];
double delz1 = x[i1][2] - x[i2][2];
domain->minimum_image(delx1,dely1,delz1);
double r1 = sqrt(delx1*delx1 + dely1*dely1 + delz1*delz1);
double delx2 = x[i3][0] - x[i2][0];
double dely2 = x[i3][1] - x[i2][1];
double delz2 = x[i3][2] - x[i2][2];
domain->minimum_image(delx2,dely2,delz2);
double r2 = sqrt(delx2*delx2 + dely2*dely2 + delz2*delz2);
double c = delx1*delx2 + dely1*dely2 + delz1*delz2;
c /= r1*r2;
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
double theta = acos(c);
double s = sqrt(1.0 - c*c);
if (s < SMALL) s = SMALL;
double dtheta = theta - theta0[type];
double dtheta2 = dtheta * dtheta;
double dtheta3 = dtheta2 * dtheta;
du = -(2.0 * k2[type] * dtheta + 3.0 * k3[type] * dtheta2 + 4.0 * k4[type] * dtheta3) / s;
du2 = (2.0 * k2[type] + 6.0 * k3[type] * dtheta + 12.0 * k4[type] * dtheta2) / (s*s) -
(2.0 * k2[type] * dtheta + 3.0 * k3[type] * dtheta2 + 4.0 * k4[type] * dtheta3) * c / (s*s*s);
}

View File

@ -35,6 +35,7 @@ class AngleQuartic : public Angle {
void read_restart(FILE *) override;
void write_data(FILE *) override;
double single(int, int, int, int) override;
void born_matrix(int type, int i1, int i2, int i3, double &du, double &du2) override;
protected:
double *k2, *k3, *k4, *theta0;

View File

@ -35,6 +35,7 @@ BondGaussian::BondGaussian(LAMMPS *lmp) :
Bond(lmp), nterms(nullptr), bond_temperature(nullptr), alpha(nullptr), width(nullptr),
r0(nullptr)
{
born_matrix_enable = 1;
}
/* ---------------------------------------------------------------------- */
@ -294,3 +295,45 @@ double BondGaussian::single(int type, double rsq, int /*i*/, int /*j*/, double &
return -(force->boltz * bond_temperature[type]) * log(sum_g_i);
}
/* ---------------------------------------------------------------------- */
void BondGaussian::born_matrix(int type, double rsq, int /*i*/, int /*j*/, double &du, double &du2)
{
double r = sqrt(rsq);
// first derivative of energy with respect to distance
double sum_g_i = 0.0;
double sum_numerator = 0.0;
for (int i = 0; i < nterms[type]; i++) {
double dr = r - r0[type][i];
double prefactor = (alpha[type][i] / (width[type][i] * sqrt(MY_PI2)));
double exponent = -2 * dr * dr / (width[type][i] * width[type][i]);
double g_i = prefactor * exp(exponent);
sum_g_i += g_i;
sum_numerator += g_i * dr / (width[type][i] * width[type][i]);
}
if (sum_g_i < SMALL) sum_g_i = SMALL;
du = 4.0 * (force->boltz * bond_temperature[type]) * (sum_numerator / sum_g_i);
// second derivative of energy with respect to distance
sum_g_i = 0.0;
double sum_dg_i = 0.0;
double sum_d2g_i = 0.0;
for (int i = 0; i < nterms[type]; i++) {
double dr = r - r0[type][i];
double prefactor = (alpha[type][i] / (width[type][i] * sqrt(MY_PI2)));
double exponent = -2 * dr * dr / (width[type][i] * width[type][i]);
double g_i = prefactor * exp(exponent);
sum_g_i += g_i;
sum_dg_i -= 4.0 * g_i * dr / pow(width[type][i], 2);
sum_d2g_i += 4.0 * g_i * (4.0 * pow(r0[type][i], 2) - 8.0 * r0[type][i] * r - pow(width[type][i], 2) + 4.0 * r * r) / pow(width[type][i], 4) ;
}
if (sum_g_i < SMALL) sum_g_i = SMALL;
double numerator = sum_d2g_i*sum_g_i - sum_dg_i*sum_dg_i;
double denominator = sum_g_i * sum_g_i;
du2 = - (force->boltz * bond_temperature[type]) * numerator / denominator;
}

View File

@ -35,6 +35,7 @@ class BondGaussian : public Bond {
void read_restart(FILE *) override;
void write_data(FILE *) override;
double single(int, double, int, int, double &) override;
void born_matrix(int, double, int, int, double &, double &) override;
protected:
int *nterms;

View File

@ -31,7 +31,10 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
BondHarmonicShiftCut::BondHarmonicShiftCut(LAMMPS *lmp) : Bond(lmp) {}
BondHarmonicShiftCut::BondHarmonicShiftCut(LAMMPS *lmp) : Bond(lmp)
{
born_matrix_enable = 1;
}
/* ---------------------------------------------------------------------- */
@ -219,3 +222,19 @@ double BondHarmonicShiftCut::single(int type, double rsq, int /*i*/, int /*j*/,
fforce = -2.0*k[type]*dr/r;
return k[type]*(dr*dr - dr2*dr2);
}
/* ---------------------------------------------------------------------- */
void BondHarmonicShiftCut::born_matrix(int type, double rsq, int /*i*/, int /*j*/, double &du, double &du2)
{
du = 0.0;
du2 = 0.0;
double r = sqrt(rsq);
if (r>r1[type]) return;
double dr = r - r0[type];
du2 = 2 * k[type];
if (r > 0.0) du = du2 * dr;
}

View File

@ -35,6 +35,7 @@ class BondHarmonicShiftCut : public Bond {
void read_restart(FILE *) override;
void write_data(FILE *) override;
double single(int, double, int, int, double &) override;
void born_matrix(int, double, int, int, double &, double &) override;
protected:
double *k, *r0, *r1;

View File

@ -41,6 +41,7 @@ using namespace MathConst;
DihedralHelix::DihedralHelix(LAMMPS *lmp) : Dihedral(lmp)
{
writedata = 1;
born_matrix_enable = 1;
}
/* ---------------------------------------------------------------------- */
@ -324,3 +325,108 @@ void DihedralHelix::write_data(FILE *fp)
for (int i = 1; i <= atom->ndihedraltypes; i++)
fprintf(fp,"%d %g %g %g\n",i,aphi[i],bphi[i],cphi[i]);
}
/* ----------------------------------------------------------------------*/
void DihedralHelix::born_matrix(int nd, int i1, int i2, int i3, int i4,
double &du, double &du2)
{
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double sb1,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s12,c;
double cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
int **dihedrallist = neighbor->dihedrallist;
double **x = atom->x;
int type = dihedrallist[nd][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
// c0 calculation
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - c1mag*c1mag,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - c2mag*c2mag,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
cx = vb1y*vb2z - vb1z*vb2y;
cy = vb1z*vb2x - vb1x*vb2z;
cz = vb1x*vb2y - vb1y*vb2x;
cmag = sqrt(cx*cx + cy*cy + cz*cz);
dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag;
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE)) problem(FLERR, i1, i2, i3, i4);
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
phi = acos(c);
if (dx > 0.0) phi *= -1.0;
si = sin(phi);
if (fabs(si) < SMALLER) si = SMALLER;
siinv = 1.0/si;
du = -aphi[type] + 3.0*bphi[type]*sin(3.0*phi)*siinv +
cphi[type]*sin(phi + MY_PI4)*siinv;
du2 = -(9.0*bphi[type]*cos(3.0*phi) + cphi[type]*cos(phi + MY_PI4))*siinv*siinv +
(3.0*bphi[type]*sin(3.0*phi) + cphi[type]*sin(phi + MY_PI4))*c*siinv*siinv*siinv;
}

View File

@ -33,6 +33,7 @@ class DihedralHelix : public Dihedral {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void born_matrix(int, int, int, int, int, double &, double &) override;
protected:
double *aphi, *bphi, *cphi;

View File

@ -41,6 +41,7 @@ using namespace MathConst;
DihedralQuadratic::DihedralQuadratic(LAMMPS *lmp) : Dihedral(lmp)
{
writedata = 1;
born_matrix_enable = 1;
}
/* ---------------------------------------------------------------------- */
@ -327,3 +328,112 @@ void DihedralQuadratic::write_data(FILE *fp)
for (int i = 1; i <= atom->ndihedraltypes; i++)
fprintf(fp,"%d %g %g \n",i,k[i],phi0[i]*180.0/MY_PI);
}
/* ----------------------------------------------------------------------*/
void DihedralQuadratic::born_matrix(int nd, int i1, int i2, int i3, int i4,
double &du, double &du2)
{
double vb1x,vb1y,vb1z,vb2x,vb2y,vb2z,vb3x,vb3y,vb3z,vb2xm,vb2ym,vb2zm;
double sb1,sb3,rb1,rb3,c0,b1mag2,b1mag,b2mag2;
double b2mag,b3mag2,b3mag,ctmp,r12c1,c1mag,r12c2;
double c2mag,sc1,sc2,s12,c;
double s1,s2,cx,cy,cz,cmag,dx,phi,si,siinv,sin2;
int **dihedrallist = neighbor->dihedrallist;
double **x = atom->x;
int type = dihedrallist[nd][4];
// 1st bond
vb1x = x[i1][0] - x[i2][0];
vb1y = x[i1][1] - x[i2][1];
vb1z = x[i1][2] - x[i2][2];
// 2nd bond
vb2x = x[i3][0] - x[i2][0];
vb2y = x[i3][1] - x[i2][1];
vb2z = x[i3][2] - x[i2][2];
vb2xm = -vb2x;
vb2ym = -vb2y;
vb2zm = -vb2z;
// 3rd bond
vb3x = x[i4][0] - x[i3][0];
vb3y = x[i4][1] - x[i3][1];
vb3z = x[i4][2] - x[i3][2];
// c0 calculation
sb1 = 1.0 / (vb1x*vb1x + vb1y*vb1y + vb1z*vb1z);
sb3 = 1.0 / (vb3x*vb3x + vb3y*vb3y + vb3z*vb3z);
rb1 = sqrt(sb1);
rb3 = sqrt(sb3);
c0 = (vb1x*vb3x + vb1y*vb3y + vb1z*vb3z) * rb1*rb3;
// 1st and 2nd angle
b1mag2 = vb1x*vb1x + vb1y*vb1y + vb1z*vb1z;
b1mag = sqrt(b1mag2);
b2mag2 = vb2x*vb2x + vb2y*vb2y + vb2z*vb2z;
b2mag = sqrt(b2mag2);
b3mag2 = vb3x*vb3x + vb3y*vb3y + vb3z*vb3z;
b3mag = sqrt(b3mag2);
ctmp = vb1x*vb2x + vb1y*vb2y + vb1z*vb2z;
r12c1 = 1.0 / (b1mag*b2mag);
c1mag = ctmp * r12c1;
ctmp = vb2xm*vb3x + vb2ym*vb3y + vb2zm*vb3z;
r12c2 = 1.0 / (b2mag*b3mag);
c2mag = ctmp * r12c2;
// cos and sin of 2 angles and final c
sin2 = MAX(1.0 - c1mag*c1mag,0.0);
sc1 = sqrt(sin2);
if (sc1 < SMALL) sc1 = SMALL;
sc1 = 1.0/sc1;
sin2 = MAX(1.0 - c2mag*c2mag,0.0);
sc2 = sqrt(sin2);
if (sc2 < SMALL) sc2 = SMALL;
sc2 = 1.0/sc2;
s1 = sc1 * sc1;
s2 = sc2 * sc2;
s12 = sc1 * sc2;
c = (c0 + c1mag*c2mag) * s12;
cx = vb1y*vb2z - vb1z*vb2y;
cy = vb1z*vb2x - vb1x*vb2z;
cz = vb1x*vb2y - vb1y*vb2x;
cmag = sqrt(cx*cx + cy*cy + cz*cz);
dx = (cx*vb3x + cy*vb3y + cz*vb3z)/cmag/b3mag;
// error check
if (c > 1.0 + TOLERANCE || c < (-1.0 - TOLERANCE))
problem(FLERR, i1, i2, i3, i4);
if (c > 1.0) c = 1.0;
if (c < -1.0) c = -1.0;
phi = acos(c);
if (dx > 0.0) phi *= -1.0;
si = sin(phi);
if (fabs(si) < SMALLER) si = SMALLER;
siinv = 1.0/si;
double dphi = phi-phi0[type];
if (dphi > MY_PI) dphi -= 2*MY_PI;
else if (dphi < -MY_PI) dphi += 2*MY_PI;
du = - 2.0 * k[type] * dphi * siinv;
du2 = 2.0 * k[type] * siinv * siinv * ( 1.0 - dphi * c * siinv) ;
}

View File

@ -33,6 +33,7 @@ class DihedralQuadratic : public Dihedral {
void write_restart(FILE *) override;
void read_restart(FILE *) override;
void write_data(FILE *) override;
void born_matrix(int, int, int, int, int, double &, double &) override;
protected:
double *k, *phi0;

View File

@ -16,7 +16,7 @@
Contributing authors: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
#include "npair_full_bin_ghost_intel.h"
#include "npair_bin_ghost_intel.h"
#include "atom.h"
#include "comm.h"

View File

@ -25,8 +25,8 @@ NPairStyle(full/bin/ghost/intel,
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_BIN_GHOST_INTEL_H
#define LMP_NPAIR_FULL_BIN_GHOST_INTEL_H
#ifndef LMP_NPAIR_BIN_GHOST_INTEL_H
#define LMP_NPAIR_BIN_GHOST_INTEL_H
#include "npair_intel.h"

View File

@ -0,0 +1,298 @@
// 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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
#include "npair_bin_intel.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "neigh_list.h"
#include "neighbor.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtonIntel::NPairHalfBinNewtonIntel(LAMMPS *lmp) :
NPairIntel(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with full Newton's 3rd law
each owned atom i checks its own bin and other bins in Newton stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfBinNewtonIntel::build(NeighList *list)
{
if (nstencil / 2 > INTEL_MAX_STENCIL_CHECK)
error->all(FLERR, "Too many neighbor bins for INTEL package.");
#ifdef _LMP_INTEL_OFFLOAD
if (exclude)
error->all(FLERR, "Exclusion lists not yet supported for Intel offload");
#endif
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
hbni(list, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
hbni(list, _fix->get_double_buffers());
else
hbni(list, _fix->get_single_buffers());
_fix->stop_watch(TIME_HOST_NEIGHBOR);
}
template <class flt_t, class acc_t>
void NPairHalfBinNewtonIntel::
hbni(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) {
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
list->inum = nlocal;
int host_start = _fix->host_start_neighbor();
const int off_end = _fix->offload_end_neighbor();
#ifdef _LMP_INTEL_OFFLOAD
if (off_end) grow_stencil();
if (_fix->full_host_list()) host_start = 0;
int offload_noghost = _fix->offload_noghost();
#endif
buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end);
int need_ic = 0;
if (atom->molecular != Atom::ATOMIC)
dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax,
neighbor->cutneighmax);
#ifdef _LMP_INTEL_OFFLOAD
if (need_ic) {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,1,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,1,0,0,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,1,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,1,0,0,0>(0, list, buffers, host_start, nlocal);
}
} else {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,0,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,0,0,0,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,0,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,0,0,0,0>(0, list, buffers, host_start, nlocal);
}
}
#else
if (need_ic)
bin_newton<flt_t,acc_t,0,1,0,0,0>(0, list, buffers, host_start, nlocal);
else
bin_newton<flt_t,acc_t,0,0,0,0,0>(0, list, buffers, host_start, nlocal);
#endif
}
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtonTriIntel::NPairHalfBinNewtonTriIntel(LAMMPS *lmp) :
NPairIntel(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with Newton's 3rd law for triclinic
each owned atom i checks its own bin and other bins in triclinic stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfBinNewtonTriIntel::build(NeighList *list)
{
if (nstencil > INTEL_MAX_STENCIL)
error->all(FLERR, "Too many neighbor bins for INTEL package.");
#ifdef _LMP_INTEL_OFFLOAD
if (exclude)
error->all(FLERR, "Exclusion lists not yet supported for Intel offload");
#endif
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
hbnti(list, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
hbnti(list, _fix->get_double_buffers());
else
hbnti(list, _fix->get_single_buffers());
_fix->stop_watch(TIME_HOST_NEIGHBOR);
}
template <class flt_t, class acc_t>
void NPairHalfBinNewtonTriIntel::
hbnti(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) {
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
list->inum = nlocal;
int host_start = _fix->host_start_neighbor();
const int off_end = _fix->offload_end_neighbor();
#ifdef _LMP_INTEL_OFFLOAD
if (off_end) grow_stencil();
if (_fix->full_host_list()) host_start = 0;
int offload_noghost = _fix->offload_noghost();
#endif
buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end);
int need_ic = 0;
if (atom->molecular != Atom::ATOMIC)
dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax,
neighbor->cutneighmax);
#ifdef _LMP_INTEL_OFFLOAD
if (need_ic) {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,1,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,1,0,1,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,1,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,1,0,1,0>(0, list, buffers, host_start, nlocal);
}
} else {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,0,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,0,0,1,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,0,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,0,0,1,0>(0, list, buffers, host_start, nlocal);
}
}
#else
if (need_ic)
bin_newton<flt_t,acc_t,0,1,0,1,0>(0, list, buffers, host_start, nlocal);
else
bin_newton<flt_t,acc_t,0,0,0,1,0>(0, list, buffers, host_start, nlocal);
#endif
}
/* ---------------------------------------------------------------------- */
NPairFullBinIntel::NPairFullBinIntel(LAMMPS *lmp) : NPairIntel(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction for all neighbors
every neighbor pair appears in list of both atoms i and j
------------------------------------------------------------------------- */
void NPairFullBinIntel::build(NeighList *list)
{
if (nstencil > INTEL_MAX_STENCIL_CHECK)
error->all(FLERR, "Too many neighbor bins for INTEL package.");
#ifdef _LMP_INTEL_OFFLOAD
if (exclude)
error->all(FLERR, "Exclusion lists not yet supported for Intel offload");
#endif
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
fbi(list, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
fbi(list, _fix->get_double_buffers());
else
fbi(list, _fix->get_single_buffers());
_fix->stop_watch(TIME_HOST_NEIGHBOR);
}
template <class flt_t, class acc_t>
void NPairFullBinIntel::
fbi(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) {
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
list->inum = nlocal;
list->gnum = 0;
int host_start = _fix->host_start_neighbor();;
const int off_end = _fix->offload_end_neighbor();
#ifdef _LMP_INTEL_OFFLOAD
if (off_end) grow_stencil();
if (_fix->full_host_list()) host_start = 0;
int offload_noghost = _fix->offload_noghost();
#endif
buffers->grow_list(list, atom->nlocal, comm->nthreads,
_fix->three_body_neighbor(), off_end,
_fix->nbor_pack_width());
int need_ic = 0;
if (atom->molecular != Atom::ATOMIC)
dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax,
neighbor->cutneighmax);
#ifdef _LMP_INTEL_OFFLOAD
if (_fix->three_body_neighbor()) {
if (need_ic) {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,1,1,0,1>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,1,1,0,1>(0, list, buffers, host_start, nlocal, off_end);
} else {
bin_newton<flt_t,acc_t,0,1,1,0,1>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,1,1,0,1>(0, list, buffers, host_start, nlocal);
}
} else {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,0,1,0,1>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,0,1,0,1>(0, list, buffers, host_start, nlocal, off_end);
} else {
bin_newton<flt_t,acc_t,0,0,1,0,1>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,0,1,0,1>(0, list, buffers, host_start, nlocal);
}
}
} else {
if (need_ic) {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,1,1,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,1,1,0,0>(0, list, buffers, host_start, nlocal, off_end);
} else {
bin_newton<flt_t,acc_t,0,1,1,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,1,1,0,0>(0, list, buffers, host_start, nlocal);
}
} else {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,0,1,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,0,1,0,0>(0, list, buffers, host_start, nlocal, off_end);
} else {
bin_newton<flt_t,acc_t,0,0,1,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,0,1,0,0>(0, list, buffers, host_start, nlocal);
}
}
}
#else
if (_fix->three_body_neighbor()) {
if (need_ic)
bin_newton<flt_t,acc_t,0,1,1,0,1>(0, list, buffers, host_start, nlocal);
else
bin_newton<flt_t,acc_t,0,0,1,0,1>(0, list, buffers, host_start, nlocal);
} else {
if (need_ic)
bin_newton<flt_t,acc_t,0,1,1,0,0>(0, list, buffers, host_start, nlocal);
else
bin_newton<flt_t,acc_t,0,0,1,0,0>(0, list, buffers, host_start, nlocal);
}
#endif
}

View File

@ -14,20 +14,38 @@
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/bin/newton/intel,
NPairHalfBinNewtonIntel,
NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_INTEL);
NPairStyle(half/bin/newton/tri/intel,
NPairHalfBinNewtonTriIntel,
NP_HALF | NP_BIN | NP_NEWTON | NP_TRI | NP_INTEL);
NPairStyle(full/bin/intel,
NPairFullBinIntel,
NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI |
NP_INTEL);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_BIN_NEWTON_INTEL_TRI_H
#define LMP_NPAIR_HALF_BIN_NEWTON_INTEL_TRI_H
#ifndef LMP_NPAIR_BIN_INTEL_H
#define LMP_NPAIR_BIN_INTEL_H
#include "fix_intel.h"
#include "npair_intel.h"
namespace LAMMPS_NS {
class NPairHalfBinNewtonIntel : public NPairIntel {
public:
NPairHalfBinNewtonIntel(class LAMMPS *);
void build(class NeighList *) override;
private:
template <class flt_t, class acc_t> void hbni(NeighList *, IntelBuffers<flt_t, acc_t> *);
};
class NPairHalfBinNewtonTriIntel : public NPairIntel {
public:
NPairHalfBinNewtonTriIntel(class LAMMPS *);
@ -37,6 +55,15 @@ class NPairHalfBinNewtonTriIntel : public NPairIntel {
template <class flt_t, class acc_t> void hbnti(NeighList *, IntelBuffers<flt_t, acc_t> *);
};
class NPairFullBinIntel : public NPairIntel {
public:
NPairFullBinIntel(class LAMMPS *);
void build(class NeighList *) override;
private:
template <class flt_t, class acc_t> void fbi(NeighList *, IntelBuffers<flt_t, acc_t> *);
};
} // namespace LAMMPS_NS
#endif

View File

@ -1,44 +0,0 @@
// clang-format off
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(full/bin/intel,
NPairFullBinIntel,
NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI |
NP_INTEL);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_BIN_INTEL_H
#define LMP_NPAIR_FULL_BIN_INTEL_H
#include "fix_intel.h"
#include "npair_intel.h"
namespace LAMMPS_NS {
class NPairFullBinIntel : public NPairIntel {
public:
NPairFullBinIntel(class LAMMPS *);
void build(class NeighList *) override;
private:
template <class flt_t, class acc_t> void fbi(NeighList *, IntelBuffers<flt_t, acc_t> *);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,108 +0,0 @@
// 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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
#include "npair_half_bin_newton_intel.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "neigh_list.h"
#include "neighbor.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtonIntel::NPairHalfBinNewtonIntel(LAMMPS *lmp) :
NPairIntel(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with full Newton's 3rd law
each owned atom i checks its own bin and other bins in Newton stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfBinNewtonIntel::build(NeighList *list)
{
if (nstencil / 2 > INTEL_MAX_STENCIL_CHECK)
error->all(FLERR, "Too many neighbor bins for INTEL package.");
#ifdef _LMP_INTEL_OFFLOAD
if (exclude)
error->all(FLERR, "Exclusion lists not yet supported for Intel offload");
#endif
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
hbni(list, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
hbni(list, _fix->get_double_buffers());
else
hbni(list, _fix->get_single_buffers());
_fix->stop_watch(TIME_HOST_NEIGHBOR);
}
template <class flt_t, class acc_t>
void NPairHalfBinNewtonIntel::
hbni(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) {
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
list->inum = nlocal;
int host_start = _fix->host_start_neighbor();
const int off_end = _fix->offload_end_neighbor();
#ifdef _LMP_INTEL_OFFLOAD
if (off_end) grow_stencil();
if (_fix->full_host_list()) host_start = 0;
int offload_noghost = _fix->offload_noghost();
#endif
buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end);
int need_ic = 0;
if (atom->molecular != Atom::ATOMIC)
dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax,
neighbor->cutneighmax);
#ifdef _LMP_INTEL_OFFLOAD
if (need_ic) {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,1,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,1,0,0,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,1,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,1,0,0,0>(0, list, buffers, host_start, nlocal);
}
} else {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,0,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,0,0,0,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,0,0,0,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,0,0,0,0>(0, list, buffers, host_start, nlocal);
}
}
#else
if (need_ic)
bin_newton<flt_t,acc_t,0,1,0,0,0>(0, list, buffers, host_start, nlocal);
else
bin_newton<flt_t,acc_t,0,0,0,0,0>(0, list, buffers, host_start, nlocal);
#endif
}

View File

@ -1,43 +0,0 @@
// clang-format off
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/bin/newton/intel,
NPairHalfBinNewtonIntel,
NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_INTEL);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_BIN_NEWTON_INTEL_H
#define LMP_NPAIR_HALF_BIN_NEWTON_INTEL_H
#include "fix_intel.h"
#include "npair_intel.h"
namespace LAMMPS_NS {
class NPairHalfBinNewtonIntel : public NPairIntel {
public:
NPairHalfBinNewtonIntel(class LAMMPS *);
void build(class NeighList *) override;
private:
template <class flt_t, class acc_t> void hbni(NeighList *, IntelBuffers<flt_t, acc_t> *);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,108 +0,0 @@
// 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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
#include "npair_half_bin_newton_tri_intel.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "neigh_list.h"
#include "neighbor.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtonTriIntel::NPairHalfBinNewtonTriIntel(LAMMPS *lmp) :
NPairIntel(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with Newton's 3rd law for triclinic
each owned atom i checks its own bin and other bins in triclinic stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfBinNewtonTriIntel::build(NeighList *list)
{
if (nstencil > INTEL_MAX_STENCIL)
error->all(FLERR, "Too many neighbor bins for INTEL package.");
#ifdef _LMP_INTEL_OFFLOAD
if (exclude)
error->all(FLERR, "Exclusion lists not yet supported for Intel offload");
#endif
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
hbnti(list, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
hbnti(list, _fix->get_double_buffers());
else
hbnti(list, _fix->get_single_buffers());
_fix->stop_watch(TIME_HOST_NEIGHBOR);
}
template <class flt_t, class acc_t>
void NPairHalfBinNewtonTriIntel::
hbnti(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) {
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
list->inum = nlocal;
int host_start = _fix->host_start_neighbor();
const int off_end = _fix->offload_end_neighbor();
#ifdef _LMP_INTEL_OFFLOAD
if (off_end) grow_stencil();
if (_fix->full_host_list()) host_start = 0;
int offload_noghost = _fix->offload_noghost();
#endif
buffers->grow_list(list, atom->nlocal, comm->nthreads, 0, off_end);
int need_ic = 0;
if (atom->molecular != Atom::ATOMIC)
dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax,
neighbor->cutneighmax);
#ifdef _LMP_INTEL_OFFLOAD
if (need_ic) {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,1,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,1,0,1,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,1,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,1,0,1,0>(0, list, buffers, host_start, nlocal);
}
} else {
if (offload_noghost) {
bin_newton<flt_t,acc_t,1,0,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,1,0,0,1,0>(0, list, buffers, host_start, nlocal,
off_end);
} else {
bin_newton<flt_t,acc_t,0,0,0,1,0>(1, list, buffers, 0, off_end);
bin_newton<flt_t,acc_t,0,0,0,1,0>(0, list, buffers, host_start, nlocal);
}
}
#else
if (need_ic)
bin_newton<flt_t,acc_t,0,1,0,1,0>(0, list, buffers, host_start, nlocal);
else
bin_newton<flt_t,acc_t,0,0,0,1,0>(0, list, buffers, host_start, nlocal);
#endif
}

View File

@ -13,10 +13,10 @@
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Stan Moore (SNL)
Contributing author: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
#include "npair_halffull_trim_newton_intel.h"
#include "npair_halffull_intel.h"
#include "atom.h"
#include "comm.h"
@ -31,6 +31,232 @@ using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalffullNewtonIntel::NPairHalffullNewtonIntel(LAMMPS *lmp) : NPair(lmp) {
_fix = static_cast<FixIntel *>(modify->get_fix_by_id("package_intel"));
if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles");
}
/* ----------------------------------------------------------------------
build half list from full list
pair stored once if i,j are both owned and i < j
if j is ghost, only store if j coords are "above and to the right" of i
works if full list is a skip list
------------------------------------------------------------------------- */
template <class flt_t, class acc_t>
void NPairHalffullNewtonIntel::build_t(NeighList *list,
IntelBuffers<flt_t,acc_t> *buffers)
{
const int inum_full = list->listfull->inum;
const int nlocal = atom->nlocal;
const int e_nall = nlocal + atom->nghost;
const ATOM_T * _noalias const x = buffers->get_x();
int * _noalias const ilist = list->ilist;
int * _noalias const numneigh = list->numneigh;
int ** _noalias const firstneigh = list->firstneigh;
const int * _noalias const ilist_full = list->listfull->ilist;
const int * _noalias const numneigh_full = list->listfull->numneigh;
const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT
const double delta = 0.01 * force->angstrom;
const int triclinic = domain->triclinic;
#if defined(_OPENMP)
#pragma omp parallel
#endif
{
int tid, ifrom, ito;
IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, comm->nthreads);
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over parent full list
for (int ii = ifrom; ii < ito; ii++) {
int n = 0;
int *neighptr = ipage.vget();
const int i = ilist_full[ii];
const flt_t xtmp = x[i].x;
const flt_t ytmp = x[i].y;
const flt_t ztmp = x[i].z;
// loop over full neighbor list
const int * _noalias const jlist = firstneigh_full[i];
const int jnum = numneigh_full[i];
if (!triclinic) {
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (j < nlocal) {
if (i > j) addme = 0;
} else {
if (x[j].z < ztmp) addme = 0;
if (x[j].z == ztmp) {
if (x[j].y < ytmp) addme = 0;
if (x[j].y == ytmp && x[j].x < xtmp) addme = 0;
}
}
if (addme)
neighptr[n++] = joriginal;
}
} else {
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (j < nlocal) {
if (i > j) addme = 0;
} else {
if (fabs(x[j].z-ztmp) > delta) {
if (x[j].z < ztmp) addme = 0;
} else if (fabs(x[j].y-ytmp) > delta) {
if (x[j].y < ytmp) addme = 0;
} else {
if (x[j].x < xtmp) addme = 0;
}
}
if (addme)
neighptr[n++] = joriginal;
}
}
ilist[ii] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
int pad_end = n;
IP_PRE_neighbor_pad(pad_end, 0);
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \
avg=INTEL_COMPILE_WIDTH/2
#endif
for ( ; n < pad_end; n++)
neighptr[n] = e_nall;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
}
list->inum = inum_full;
}
/* ----------------------------------------------------------------------
build half list from full 3-body list
half list is already stored as first part of 3-body list
------------------------------------------------------------------------- */
template <class flt_t>
void NPairHalffullNewtonIntel::build_t3(NeighList *list, int *numhalf)
{
const int inum_full = list->listfull->inum;
const int e_nall = atom->nlocal + atom->nghost;
int * _noalias const ilist = list->ilist;
int * _noalias const numneigh = list->numneigh;
int ** _noalias const firstneigh = list->firstneigh;
const int * _noalias const ilist_full = list->listfull->ilist;
const int * _noalias const numneigh_full = numhalf;
const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT
int packthreads = 1;
if (comm->nthreads > INTEL_HTHREADS) packthreads = comm->nthreads;
#if defined(_OPENMP)
#pragma omp parallel if (packthreads > 1)
#endif
{
int tid, ifrom, ito;
IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, packthreads);
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over parent full list
for (int ii = ifrom; ii < ito; ii++) {
int n = 0;
int *neighptr = ipage.vget();
const int i = ilist_full[ii];
// loop over full neighbor list
const int * _noalias const jlist = firstneigh_full[i];
const int jnum = numneigh_full[ii];
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
neighptr[n++] = joriginal;
}
ilist[ii] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
int pad_end = n;
IP_PRE_neighbor_pad(pad_end, 0);
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \
avg=INTEL_COMPILE_WIDTH/2
#endif
for ( ; n < pad_end; n++)
neighptr[n] = e_nall;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
}
list->inum = inum_full;
}
/* ---------------------------------------------------------------------- */
void NPairHalffullNewtonIntel::build(NeighList *list)
{
if (_fix->three_body_neighbor() == 0 || domain->triclinic) {
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
build_t(list, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
build_t(list, _fix->get_double_buffers());
else
build_t(list, _fix->get_single_buffers());
} else {
int *nhalf, *cnum;
if (_fix->precision() == FixIntel::PREC_MODE_MIXED) {
_fix->get_mixed_buffers()->get_list_data3(list->listfull, nhalf, cnum);
build_t3<float>(list, nhalf);
} else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) {
_fix->get_double_buffers()->get_list_data3(list->listfull, nhalf, cnum);
build_t3<double>(list, nhalf);
} else {
_fix->get_single_buffers()->get_list_data3(list->listfull, nhalf, cnum);
build_t3<float>(list, nhalf);
}
}
}
/* ---------------------------------------------------------------------- */
NPairHalffullTrimNewtonIntel::NPairHalffullTrimNewtonIntel(LAMMPS *lmp) : NPair(lmp) {
_fix = static_cast<FixIntel *>(modify->get_fix_by_id("package_intel"));
if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles");

View File

@ -0,0 +1,128 @@
// clang-format off
/* -*- 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: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
// For Newton off, only used for hybrid to generate list for non-intel style.
// Use standard routines.
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(halffull/newton/intel,
NPairHalffullNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI| NP_INTEL);
NPairStyle(halffull/newton/skip/intel,
NPairHalffullNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL);
NPairStyle(halffull/newtoff/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_INTEL);
NPairStyle(halffull/newtoff/skip/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL);
NPairStyle(halffull/newtoff/ghost/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_GHOST | NP_INTEL);
NPairStyle(halffull/newtoff/skip/ghost/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_INTEL);
NPairStyle(halffull/trim/newton/intel,
NPairHalffullTrimNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI| NP_TRIM | NP_INTEL);
NPairStyle(halffull/trim/newton/skip/intel,
NPairHalffullTrimNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_INTEL);
NPairStyle(halffull/trim/newtoff/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL);
NPairStyle(halffull/trim/newtoff/skip/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_INTEL);
NPairStyle(halffull/trim/newtoff/ghost/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_GHOST | NP_TRIM | NP_INTEL);
NPairStyle(halffull/trim/newtoff/skip/ghost/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_TRIM | NP_INTEL);
// clang-format on
#else
#ifndef LMP_NPAIR_HALFFULL_INTEL_H
#define LMP_NPAIR_HALFFULL_INTEL_H
#include "fix_intel.h"
#include "npair.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
namespace LAMMPS_NS {
class NPairHalffullNewtonIntel : public NPair {
public:
NPairHalffullNewtonIntel(class LAMMPS *);
void build(class NeighList *) override;
protected:
FixIntel *_fix;
template <class flt_t, class acc_t> void build_t(NeighList *, IntelBuffers<flt_t, acc_t> *);
template <class flt_t> void build_t3(NeighList *, int *);
};
class NPairHalffullTrimNewtonIntel : public NPair {
public:
NPairHalffullTrimNewtonIntel(class LAMMPS *);
void build(class NeighList *) override;
protected:
FixIntel *_fix;
template <class flt_t, class acc_t> void build_t(NeighList *, IntelBuffers<flt_t, acc_t> *);
template <class flt_t, class acc_t> void build_t3(NeighList *, int *, IntelBuffers<flt_t, acc_t> *);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,44 +0,0 @@
// clang-format off
/* -*- 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: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
// Only used for hybrid to generate list for non-intel style. Use
// standard routines.
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(halffull/newtoff/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_INTEL);
NPairStyle(halffull/newtoff/skip/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL);
NPairStyle(halffull/newtoff/ghost/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_GHOST | NP_INTEL);
NPairStyle(halffull/newtoff/skip/ghost/intel,
NPairHalffullNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_SKIP | NP_GHOST | NP_INTEL);
// clang-format on
#endif

View File

@ -1,256 +0,0 @@
// 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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
#include "npair_halffull_newton_intel.h"
#include "atom.h"
#include "comm.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "modify.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalffullNewtonIntel::NPairHalffullNewtonIntel(LAMMPS *lmp) : NPair(lmp) {
_fix = static_cast<FixIntel *>(modify->get_fix_by_id("package_intel"));
if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles");
}
/* ----------------------------------------------------------------------
build half list from full list
pair stored once if i,j are both owned and i < j
if j is ghost, only store if j coords are "above and to the right" of i
works if full list is a skip list
------------------------------------------------------------------------- */
template <class flt_t, class acc_t>
void NPairHalffullNewtonIntel::build_t(NeighList *list,
IntelBuffers<flt_t,acc_t> *buffers)
{
const int inum_full = list->listfull->inum;
const int nlocal = atom->nlocal;
const int e_nall = nlocal + atom->nghost;
const ATOM_T * _noalias const x = buffers->get_x();
int * _noalias const ilist = list->ilist;
int * _noalias const numneigh = list->numneigh;
int ** _noalias const firstneigh = list->firstneigh;
const int * _noalias const ilist_full = list->listfull->ilist;
const int * _noalias const numneigh_full = list->listfull->numneigh;
const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT
const double delta = 0.01 * force->angstrom;
const int triclinic = domain->triclinic;
#if defined(_OPENMP)
#pragma omp parallel
#endif
{
int tid, ifrom, ito;
IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, comm->nthreads);
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over parent full list
for (int ii = ifrom; ii < ito; ii++) {
int n = 0;
int *neighptr = ipage.vget();
const int i = ilist_full[ii];
const flt_t xtmp = x[i].x;
const flt_t ytmp = x[i].y;
const flt_t ztmp = x[i].z;
// loop over full neighbor list
const int * _noalias const jlist = firstneigh_full[i];
const int jnum = numneigh_full[i];
if (!triclinic) {
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (j < nlocal) {
if (i > j) addme = 0;
} else {
if (x[j].z < ztmp) addme = 0;
if (x[j].z == ztmp) {
if (x[j].y < ytmp) addme = 0;
if (x[j].y == ytmp && x[j].x < xtmp) addme = 0;
}
}
if (addme)
neighptr[n++] = joriginal;
}
} else {
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (j < nlocal) {
if (i > j) addme = 0;
} else {
if (fabs(x[j].z-ztmp) > delta) {
if (x[j].z < ztmp) addme = 0;
} else if (fabs(x[j].y-ytmp) > delta) {
if (x[j].y < ytmp) addme = 0;
} else {
if (x[j].x < xtmp) addme = 0;
}
}
if (addme)
neighptr[n++] = joriginal;
}
}
ilist[ii] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
int pad_end = n;
IP_PRE_neighbor_pad(pad_end, 0);
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \
avg=INTEL_COMPILE_WIDTH/2
#endif
for ( ; n < pad_end; n++)
neighptr[n] = e_nall;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
}
list->inum = inum_full;
}
/* ----------------------------------------------------------------------
build half list from full 3-body list
half list is already stored as first part of 3-body list
------------------------------------------------------------------------- */
template <class flt_t>
void NPairHalffullNewtonIntel::build_t3(NeighList *list, int *numhalf)
{
const int inum_full = list->listfull->inum;
const int e_nall = atom->nlocal + atom->nghost;
int * _noalias const ilist = list->ilist;
int * _noalias const numneigh = list->numneigh;
int ** _noalias const firstneigh = list->firstneigh;
const int * _noalias const ilist_full = list->listfull->ilist;
const int * _noalias const numneigh_full = numhalf;
const int ** _noalias const firstneigh_full = (const int ** const)list->listfull->firstneigh; // NOLINT
int packthreads = 1;
if (comm->nthreads > INTEL_HTHREADS) packthreads = comm->nthreads;
#if defined(_OPENMP)
#pragma omp parallel if (packthreads > 1)
#endif
{
int tid, ifrom, ito;
IP_PRE_omp_range_id(ifrom, ito, tid, inum_full, packthreads);
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over parent full list
for (int ii = ifrom; ii < ito; ii++) {
int n = 0;
int *neighptr = ipage.vget();
const int i = ilist_full[ii];
// loop over full neighbor list
const int * _noalias const jlist = firstneigh_full[i];
const int jnum = numneigh_full[ii];
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
neighptr[n++] = joriginal;
}
ilist[ii] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
int pad_end = n;
IP_PRE_neighbor_pad(pad_end, 0);
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \
avg=INTEL_COMPILE_WIDTH/2
#endif
for ( ; n < pad_end; n++)
neighptr[n] = e_nall;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
}
list->inum = inum_full;
}
/* ---------------------------------------------------------------------- */
void NPairHalffullNewtonIntel::build(NeighList *list)
{
if (_fix->three_body_neighbor() == 0 || domain->triclinic) {
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
build_t(list, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
build_t(list, _fix->get_double_buffers());
else
build_t(list, _fix->get_single_buffers());
} else {
int *nhalf, *cnum;
if (_fix->precision() == FixIntel::PREC_MODE_MIXED) {
_fix->get_mixed_buffers()->get_list_data3(list->listfull, nhalf, cnum);
build_t3<float>(list, nhalf);
} else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) {
_fix->get_double_buffers()->get_list_data3(list->listfull, nhalf, cnum);
build_t3<double>(list, nhalf);
} else {
_fix->get_single_buffers()->get_list_data3(list->listfull, nhalf, cnum);
build_t3<float>(list, nhalf);
}
}
}

View File

@ -1,61 +0,0 @@
// clang-format off
/* -*- 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: W. Michael Brown (Intel)
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(halffull/newton/intel,
NPairHalffullNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI| NP_INTEL);
NPairStyle(halffull/newton/skip/intel,
NPairHalffullNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI | NP_SKIP | NP_INTEL);
// clang-format on
#else
#ifndef LMP_NPAIR_HALFFULL_NEWTON_INTEL_H
#define LMP_NPAIR_HALFFULL_NEWTON_INTEL_H
#include "fix_intel.h"
#include "npair.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
namespace LAMMPS_NS {
class NPairHalffullNewtonIntel : public NPair {
public:
NPairHalffullNewtonIntel(class LAMMPS *);
void build(class NeighList *) override;
protected:
FixIntel *_fix;
template <class flt_t, class acc_t> void build_t(NeighList *, IntelBuffers<flt_t, acc_t> *);
template <class flt_t> void build_t3(NeighList *, int *);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,44 +0,0 @@
// clang-format off
/* -*- 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: Stan Moore (SNL)
------------------------------------------------------------------------- */
// Only used for hybrid to generate list for non-intel style. Use
// standard routines.
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(halffull/trim/newtoff/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL);
NPairStyle(halffull/trim/newtoff/skip/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP | NP_INTEL);
NPairStyle(halffull/trim/newtoff/ghost/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_TRIM | NP_GHOST | NP_INTEL);
NPairStyle(halffull/trim/newtoff/skip/ghost/intel,
NPairHalffullTrimNewtoff,
NP_HALF_FULL | NP_NEWTOFF | NP_NSQ | NP_BIN | NP_MULTI | NP_HALF |
NP_ORTHO | NP_TRI | NP_TRIM | NP_SKIP | NP_GHOST | NP_INTEL);
// clang-format on
#endif

View File

@ -1,61 +0,0 @@
// clang-format off
/* -*- 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: Stan Moore (SNL)
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(halffull/trim/newton/intel,
NPairHalffullTrimNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI| NP_TRIM | NP_INTEL);
NPairStyle(halffull/trim/newton/skip/intel,
NPairHalffullTrimNewtonIntel,
NP_HALF_FULL | NP_NEWTON | NP_HALF | NP_NSQ | NP_BIN | NP_MULTI |
NP_ORTHO | NP_TRI | NP_SKIP | NP_TRIM | NP_INTEL);
// clang-format on
#else
#ifndef LMP_NPAIR_HALFFULL_TRIM_NEWTON_INTEL_H
#define LMP_NPAIR_HALFFULL_TRIM_NEWTON_INTEL_H
#include "fix_intel.h"
#include "npair.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
namespace LAMMPS_NS {
class NPairHalffullTrimNewtonIntel : public NPair {
public:
NPairHalffullTrimNewtonIntel(class LAMMPS *);
void build(class NeighList *) override;
protected:
FixIntel *_fix;
template <class flt_t, class acc_t> void build_t(NeighList *, IntelBuffers<flt_t, acc_t> *);
template <class flt_t, class acc_t> void build_t3(NeighList *, int *, IntelBuffers<flt_t, acc_t> *);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -13,7 +13,7 @@
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: W. Michael Brown (Intel)
Contributing author: W. Michael Brown (Intel), Stan Moore (SNL)
------------------------------------------------------------------------- */
#include "npair_skip_intel.h"
@ -224,3 +224,244 @@ void NPairSkipIntel::build(NeighList *list)
}
}
}
/* ---------------------------------------------------------------------- */
NPairSkipTrimIntel::NPairSkipTrimIntel(LAMMPS *lmp) : NPair(lmp) {
_fix = static_cast<FixIntel *>(modify->get_fix_by_id("package_intel"));
if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles");
_inum_starts = new int[comm->nthreads];
_inum_counts = new int[comm->nthreads];
_full_props = nullptr;
}
/* ---------------------------------------------------------------------- */
NPairSkipTrimIntel::~NPairSkipTrimIntel() {
delete []_inum_starts;
delete []_inum_counts;
delete[] _full_props;
}
/* ---------------------------------------------------------------------- */
void NPairSkipTrimIntel::copy_neighbor_info()
{
NPair::copy_neighbor_info();
// Only need to set _full_props once; npair object deleted for changes
if (_full_props) return;
_full_props = new int[neighbor->nrequest];
for (int i = 0; i < neighbor->nrequest; i++)
_full_props[i] = neighbor->requests[i]->full;
}
/* ----------------------------------------------------------------------
build skip list for subset of types from parent list
works for half and full lists
works for owned (non-ghost) list, also for ghost list
iskip and ijskip flag which atom types and type pairs to skip
if ghost, also store neighbors of ghost atoms & set inum,gnum correctly
------------------------------------------------------------------------- */
template<class flt_t, class acc_t, int THREE>
void NPairSkipTrimIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh,
int *numhalf_skip, IntelBuffers<flt_t,acc_t> *buffers)
{
const int nlocal = atom->nlocal;
const int e_nall = nlocal + atom->nghost;
const ATOM_T * _noalias const x = buffers->get_x();
const int * _noalias const type = atom->type;
int * _noalias const ilist = list->ilist;
int * _noalias const numneigh = list->numneigh;
int ** _noalias const firstneigh = (int ** const)list->firstneigh; // NOLINT
const int * _noalias const ilist_skip = list->listskip->ilist;
const int * _noalias const numneigh_skip = list->listskip->numneigh;
const int ** _noalias const firstneigh_skip = (const int ** const)list->listskip->firstneigh; // NOLINT
const int * _noalias const iskip = list->iskip;
const int ** _noalias const ijskip = (const int ** const)list->ijskip; // NOLINT
const flt_t cutsq_custom = cutoff_custom * cutoff_custom;
int num_skip = list->listskip->inum;
if (list->ghost) num_skip += list->listskip->gnum;
int packthreads;
if (comm->nthreads > INTEL_HTHREADS && THREE==0)
packthreads = comm->nthreads;
else
packthreads = 1;
#if defined(_OPENMP)
#pragma omp parallel if (packthreads > 1)
#endif
{
int tid, ifrom, ito;
IP_PRE_omp_range_id(ifrom, ito, tid, num_skip, packthreads);
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
int my_inum = ifrom;
_inum_starts[tid] = ifrom;
// loop over parent full list
for (int ii = ifrom; ii < ito; ii++) {
const int i = ilist_skip[ii];
const int itype = type[i];
if (iskip[itype]) continue;
const flt_t xtmp = x[i].x;
const flt_t ytmp = x[i].y;
const flt_t ztmp = x[i].z;
int n = 0;
int *neighptr = ipage.vget();
// loop over parent non-skip list
const int * _noalias const jlist = firstneigh_skip[i];
const int jnum = numneigh_skip[i];
if (THREE) {
const int jnumhalf = numhalf_skip[ii];
for (int jj = 0; jj < jnumhalf; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (ijskip[itype][type[j]]) addme = 0;
// trim to shorter cutoff
const flt_t delx = xtmp - x[j].x;
const flt_t dely = ytmp - x[j].y;
const flt_t delz = ztmp - x[j].z;
const flt_t rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq_custom) addme = 0;
if (addme)
neighptr[n++] = joriginal;
}
numhalf[my_inum] = n;
for (int jj = jnumhalf; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (ijskip[itype][type[j]]) addme = 0;
// trim to shorter cutoff
const flt_t delx = xtmp - x[j].x;
const flt_t dely = ytmp - x[j].y;
const flt_t delz = ztmp - x[j].z;
const flt_t rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq_custom) addme = 0;
if (addme)
neighptr[n++] = joriginal;
}
} else {
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (ijskip[itype][type[j]]) addme = 0;
// trim to shorter cutoff
const flt_t delx = xtmp - x[j].x;
const flt_t dely = ytmp - x[j].y;
const flt_t delz = ztmp - x[j].z;
const flt_t rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq_custom) addme = 0;
if (addme)
neighptr[n++] = joriginal;
}
}
ilist[my_inum++] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
int pad_end = n;
IP_PRE_neighbor_pad(pad_end, 0);
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \
avg=INTEL_COMPILE_WIDTH/2
#endif
for ( ; n < pad_end; n++)
neighptr[n] = e_nall;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
int last_inum = 0, loop_end;
_inum_counts[tid] = my_inum;
}
int inum = _inum_counts[0];
for (int tid = 1; tid < packthreads; tid++) {
for (int i = _inum_starts[tid]; i < _inum_counts[tid]; i++) {
if (THREE) numhalf[inum] = numhalf[i];
ilist[inum++] = ilist[i];
}
}
list->inum = inum;
if (THREE && num_skip > 0) {
int * const list_start = firstneigh[ilist[0]];
for (int ii = 0; ii < inum; ii++) {
int i = ilist[ii];
cnumneigh[ii] = static_cast<int>(firstneigh[i] - list_start);
}
}
if (list->ghost) {
int num = 0;
int my_inum = list->inum;
for (int i = 0; i < my_inum; i++)
if (ilist[i] < nlocal) num++;
else break;
list->inum = num;
list->gnum = my_inum - num;
}
}
/* ---------------------------------------------------------------------- */
void NPairSkipTrimIntel::build(NeighList *list)
{
if (_fix->three_body_neighbor()==0 ||
_full_props[list->listskip->index] == 0) {
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
build_t<float,double,0>(list, nullptr, nullptr, nullptr, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
build_t<double,double,0>(list, nullptr, nullptr, nullptr, _fix->get_double_buffers());
else
build_t<float,float,0>(list, nullptr, nullptr, nullptr, _fix->get_single_buffers());
} else {
int *nhalf, *cnumneigh, *nhalf_skip, *u;
if (_fix->precision() == FixIntel::PREC_MODE_MIXED) {
_fix->get_mixed_buffers()->get_list_data3(list->listskip,nhalf_skip,u);
_fix->get_mixed_buffers()->grow_data3(list, nhalf, cnumneigh);
build_t<float,double,1>(list, nhalf, cnumneigh, nhalf_skip, _fix->get_mixed_buffers());
} else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) {
_fix->get_double_buffers()->get_list_data3(list->listskip,nhalf_skip,u);
_fix->get_double_buffers()->grow_data3(list, nhalf, cnumneigh);
build_t<double,double,1>(list, nhalf, cnumneigh, nhalf_skip, _fix->get_double_buffers());
} else {
_fix->get_single_buffers()->get_list_data3(list->listskip,nhalf_skip,u);
_fix->get_single_buffers()->grow_data3(list,nhalf,cnumneigh);
build_t<float,float,1>(list, nhalf, cnumneigh, nhalf_skip, _fix->get_single_buffers());
}
}
}

View File

@ -25,6 +25,18 @@ NPairStyle(skip/ghost/intel,
NP_SKIP | NP_HALF | NP_FULL |
NP_NSQ | NP_BIN | NP_MULTI |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_GHOST | NP_INTEL);
NPairStyle(skip/trim/intel,
NPairSkipTrimIntel,
NP_SKIP | NP_HALF | NP_FULL |
NP_NSQ | NP_BIN | NP_MULTI |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL);
NPairStyle(skip/trim/ghost/intel,
NPairSkipTrimIntel,
NP_SKIP | NP_HALF | NP_FULL |
NP_NSQ | NP_BIN | NP_MULTI |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_GHOST | NP_INTEL);
// clang-format on
#else
@ -55,6 +67,22 @@ class NPairSkipIntel : public NPair {
void build_t(NeighList *, int *numhalf, int *cnumneigh, int *numhalf_skip);
};
class NPairSkipTrimIntel : public NPair {
public:
NPairSkipTrimIntel(class LAMMPS *);
~NPairSkipTrimIntel() override;
void copy_neighbor_info() override;
void build(class NeighList *) override;
protected:
FixIntel *_fix;
int *_inum_starts, *_inum_counts, *_full_props;
template <class flt_t, class acc_t, int THREE>
void build_t(NeighList *, int *numhalf, int *cnumneigh, int *numhalf_skip,
IntelBuffers<flt_t, acc_t> *);
};
} // namespace LAMMPS_NS
#endif

View File

@ -1,271 +0,0 @@
// 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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Stan Moore (SNL)
------------------------------------------------------------------------- */
#include "npair_skip_trim_intel.h"
#include "atom.h"
#include "comm.h"
#include "error.h"
#include "modify.h"
#include "my_page.h"
#include "neigh_list.h"
#include "neigh_request.h"
#include "neighbor.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairSkipTrimIntel::NPairSkipTrimIntel(LAMMPS *lmp) : NPair(lmp) {
_fix = static_cast<FixIntel *>(modify->get_fix_by_id("package_intel"));
if (!_fix) error->all(FLERR, "The 'package intel' command is required for /intel styles");
_inum_starts = new int[comm->nthreads];
_inum_counts = new int[comm->nthreads];
_full_props = nullptr;
}
/* ---------------------------------------------------------------------- */
NPairSkipTrimIntel::~NPairSkipTrimIntel() {
delete []_inum_starts;
delete []_inum_counts;
delete[] _full_props;
}
/* ---------------------------------------------------------------------- */
void NPairSkipTrimIntel::copy_neighbor_info()
{
NPair::copy_neighbor_info();
// Only need to set _full_props once; npair object deleted for changes
if (_full_props) return;
_full_props = new int[neighbor->nrequest];
for (int i = 0; i < neighbor->nrequest; i++)
_full_props[i] = neighbor->requests[i]->full;
}
/* ----------------------------------------------------------------------
build skip list for subset of types from parent list
works for half and full lists
works for owned (non-ghost) list, also for ghost list
iskip and ijskip flag which atom types and type pairs to skip
if ghost, also store neighbors of ghost atoms & set inum,gnum correctly
------------------------------------------------------------------------- */
template<class flt_t, class acc_t, int THREE>
void NPairSkipTrimIntel::build_t(NeighList *list, int *numhalf, int *cnumneigh,
int *numhalf_skip, IntelBuffers<flt_t,acc_t> *buffers)
{
const int nlocal = atom->nlocal;
const int e_nall = nlocal + atom->nghost;
const ATOM_T * _noalias const x = buffers->get_x();
const int * _noalias const type = atom->type;
int * _noalias const ilist = list->ilist;
int * _noalias const numneigh = list->numneigh;
int ** _noalias const firstneigh = (int ** const)list->firstneigh; // NOLINT
const int * _noalias const ilist_skip = list->listskip->ilist;
const int * _noalias const numneigh_skip = list->listskip->numneigh;
const int ** _noalias const firstneigh_skip = (const int ** const)list->listskip->firstneigh; // NOLINT
const int * _noalias const iskip = list->iskip;
const int ** _noalias const ijskip = (const int ** const)list->ijskip; // NOLINT
const flt_t cutsq_custom = cutoff_custom * cutoff_custom;
int num_skip = list->listskip->inum;
if (list->ghost) num_skip += list->listskip->gnum;
int packthreads;
if (comm->nthreads > INTEL_HTHREADS && THREE==0)
packthreads = comm->nthreads;
else
packthreads = 1;
#if defined(_OPENMP)
#pragma omp parallel if (packthreads > 1)
#endif
{
int tid, ifrom, ito;
IP_PRE_omp_range_id(ifrom, ito, tid, num_skip, packthreads);
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
int my_inum = ifrom;
_inum_starts[tid] = ifrom;
// loop over parent full list
for (int ii = ifrom; ii < ito; ii++) {
const int i = ilist_skip[ii];
const int itype = type[i];
if (iskip[itype]) continue;
const flt_t xtmp = x[i].x;
const flt_t ytmp = x[i].y;
const flt_t ztmp = x[i].z;
int n = 0;
int *neighptr = ipage.vget();
// loop over parent non-skip list
const int * _noalias const jlist = firstneigh_skip[i];
const int jnum = numneigh_skip[i];
if (THREE) {
const int jnumhalf = numhalf_skip[ii];
for (int jj = 0; jj < jnumhalf; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (ijskip[itype][type[j]]) addme = 0;
// trim to shorter cutoff
const flt_t delx = xtmp - x[j].x;
const flt_t dely = ytmp - x[j].y;
const flt_t delz = ztmp - x[j].z;
const flt_t rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq_custom) addme = 0;
if (addme)
neighptr[n++] = joriginal;
}
numhalf[my_inum] = n;
for (int jj = jnumhalf; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (ijskip[itype][type[j]]) addme = 0;
// trim to shorter cutoff
const flt_t delx = xtmp - x[j].x;
const flt_t dely = ytmp - x[j].y;
const flt_t delz = ztmp - x[j].z;
const flt_t rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq_custom) addme = 0;
if (addme)
neighptr[n++] = joriginal;
}
} else {
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma ivdep
#endif
for (int jj = 0; jj < jnum; jj++) {
const int joriginal = jlist[jj];
const int j = joriginal & NEIGHMASK;
int addme = 1;
if (ijskip[itype][type[j]]) addme = 0;
// trim to shorter cutoff
const flt_t delx = xtmp - x[j].x;
const flt_t dely = ytmp - x[j].y;
const flt_t delz = ztmp - x[j].z;
const flt_t rsq = delx * delx + dely * dely + delz * delz;
if (rsq > cutsq_custom) addme = 0;
if (addme)
neighptr[n++] = joriginal;
}
}
ilist[my_inum++] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
int pad_end = n;
IP_PRE_neighbor_pad(pad_end, 0);
#if defined(LMP_SIMD_COMPILER)
#pragma vector aligned
#pragma loop_count min=1, max=INTEL_COMPILE_WIDTH-1, \
avg=INTEL_COMPILE_WIDTH/2
#endif
for ( ; n < pad_end; n++)
neighptr[n] = e_nall;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
int last_inum = 0, loop_end;
_inum_counts[tid] = my_inum;
}
int inum = _inum_counts[0];
for (int tid = 1; tid < packthreads; tid++) {
for (int i = _inum_starts[tid]; i < _inum_counts[tid]; i++) {
if (THREE) numhalf[inum] = numhalf[i];
ilist[inum++] = ilist[i];
}
}
list->inum = inum;
if (THREE && num_skip > 0) {
int * const list_start = firstneigh[ilist[0]];
for (int ii = 0; ii < inum; ii++) {
int i = ilist[ii];
cnumneigh[ii] = static_cast<int>(firstneigh[i] - list_start);
}
}
if (list->ghost) {
int num = 0;
int my_inum = list->inum;
for (int i = 0; i < my_inum; i++)
if (ilist[i] < nlocal) num++;
else break;
list->inum = num;
list->gnum = my_inum - num;
}
}
/* ---------------------------------------------------------------------- */
void NPairSkipTrimIntel::build(NeighList *list)
{
if (_fix->three_body_neighbor()==0 ||
_full_props[list->listskip->index] == 0) {
if (_fix->precision() == FixIntel::PREC_MODE_MIXED)
build_t<float,double,0>(list, nullptr, nullptr, nullptr, _fix->get_mixed_buffers());
else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE)
build_t<double,double,0>(list, nullptr, nullptr, nullptr, _fix->get_double_buffers());
else
build_t<float,float,0>(list, nullptr, nullptr, nullptr, _fix->get_single_buffers());
} else {
int *nhalf, *cnumneigh, *nhalf_skip, *u;
if (_fix->precision() == FixIntel::PREC_MODE_MIXED) {
_fix->get_mixed_buffers()->get_list_data3(list->listskip,nhalf_skip,u);
_fix->get_mixed_buffers()->grow_data3(list, nhalf, cnumneigh);
build_t<float,double,1>(list, nhalf, cnumneigh, nhalf_skip, _fix->get_mixed_buffers());
} else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) {
_fix->get_double_buffers()->get_list_data3(list->listskip,nhalf_skip,u);
_fix->get_double_buffers()->grow_data3(list, nhalf, cnumneigh);
build_t<double,double,1>(list, nhalf, cnumneigh, nhalf_skip, _fix->get_double_buffers());
} else {
_fix->get_single_buffers()->get_list_data3(list->listskip,nhalf_skip,u);
_fix->get_single_buffers()->grow_data3(list,nhalf,cnumneigh);
build_t<float,float,1>(list, nhalf, cnumneigh, nhalf_skip, _fix->get_single_buffers());
}
}
}

View File

@ -1,62 +0,0 @@
// clang-format off
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(skip/trim/intel,
NPairSkipTrimIntel,
NP_SKIP | NP_HALF | NP_FULL |
NP_NSQ | NP_BIN | NP_MULTI |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_INTEL);
NPairStyle(skip/trim/ghost/intel,
NPairSkipTrimIntel,
NP_SKIP | NP_HALF | NP_FULL |
NP_NSQ | NP_BIN | NP_MULTI |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_TRIM | NP_GHOST | NP_INTEL);
// clang-format on
#else
#ifndef LMP_NPAIR_SKIP_TRIM_INTEL_H
#define LMP_NPAIR_SKIP_TRIM_INTEL_H
#include "fix_intel.h"
#include "npair.h"
#if defined(_OPENMP)
#include <omp.h>
#endif
namespace LAMMPS_NS {
class NPairSkipTrimIntel : public NPair {
public:
NPairSkipTrimIntel(class LAMMPS *);
~NPairSkipTrimIntel() override;
void copy_neighbor_info() override;
void build(class NeighList *) override;
protected:
FixIntel *_fix;
int *_inum_starts, *_inum_counts, *_full_props;
template <class flt_t, class acc_t, int THREE>
void build_t(NeighList *, int *numhalf, int *cnumneigh, int *numhalf_skip,
IntelBuffers<flt_t, acc_t> *);
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -0,0 +1,70 @@
/* ----------------------------------------------------------------------
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 "nstencil_bin_intel.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
template<int HALF, int DIM_3D, int TRI>
NStencilBinIntel<HALF, DIM_3D, TRI>::NStencilBinIntel(LAMMPS *lmp) : NStencil(lmp) {}
/* ----------------------------------------------------------------------
create stencil based on bin geometry and cutoff
------------------------------------------------------------------------- */
template<int HALF, int DIM_3D, int TRI>
void NStencilBinIntel<HALF, DIM_3D, TRI>::create()
{
int i, j, k;
// For half stencils, only the upper plane is needed
int sy_min = sy;
int sz_min = sz;
if ((!TRI) && HALF && (!DIM_3D)) sy_min = 0;
if ((!TRI) && HALF && DIM_3D) sz_min = 0;
nstencil = 0;
// For Intel, half and ortho stencils do not include central bin
// as, historically, this was never included in a stencil.
// Non-Intel npair classes were updated to account for this change,
// but the Intel npair classes have not yet been updated
// if (HALF && (!TRI)) stencil[nstencil++] = 0;
for (k = -sz_min; k <= sz; k++) {
for (j = -sy_min; j <= sy; j++) {
for (i = -sx; i <= sx; i++) {
// Now only include "upper right" bins for half and ortho stencils
if (HALF && (!DIM_3D) && (!TRI))
if (! (j > 0 || (j == 0 && i > 0))) continue;
if (HALF && DIM_3D && (!TRI))
if (! (k > 0 || j > 0 || (j == 0 && i > 0))) continue;
if (bin_distance(i, j, k) < cutneighmaxsq)
stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i;
}
}
}
}
namespace LAMMPS_NS {
template class NStencilBinIntel<0,0,0>;
template class NStencilBinIntel<0,1,0>;
template class NStencilBinIntel<1,0,0>;
template class NStencilBinIntel<1,0,1>;
template class NStencilBinIntel<1,1,0>;
template class NStencilBinIntel<1,1,1>;
}

View File

@ -0,0 +1,65 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NSTENCIL_CLASS
// clang-format off
typedef NStencilBinIntel<0, 0, 0> NStencilFullBin2dIntel;
NStencilStyle(full/bin/2d/intel,
NStencilFullBin2dIntel,
NS_FULL | NS_BIN | NS_2D | NS_ORTHO | NS_TRI | NS_INTEL);
typedef NStencilBinIntel<0, 1, 0> NStencilFullBin3dIntel;
NStencilStyle(full/bin/3d/intel,
NStencilFullBin3dIntel,
NS_FULL | NS_BIN | NS_3D | NS_ORTHO | NS_TRI | NS_INTEL);
typedef NStencilBinIntel<1, 0, 0> NStencilHalfBin2dIntel;
NStencilStyle(half/bin/2d/intel,
NStencilHalfBin2dIntel,
NS_HALF | NS_BIN | NS_2D | NS_ORTHO | NS_INTEL);
typedef NStencilBinIntel<1, 0, 1> NStencilHalfBin2dTriIntel;
NStencilStyle(half/bin/2d/tri/intel,
NStencilHalfBin2dTriIntel,
NS_HALF | NS_BIN | NS_2D | NS_TRI | NS_INTEL);
typedef NStencilBinIntel<1, 1, 0> NStencilHalfBin3dIntel;
NStencilStyle(half/bin/3d/intel,
NStencilHalfBin3dIntel,
NS_HALF | NS_BIN | NS_3D | NS_ORTHO | NS_INTEL);
typedef NStencilBinIntel<1, 1, 1> NStencilHalfBin3dTriIntel;
NStencilStyle(half/bin/3d/tri/intel,
NStencilHalfBin3dTriIntel,
NS_HALF | NS_BIN | NS_3D | NS_TRI | NS_INTEL);
// clang-format on
#else
#ifndef LMP_NSTENCIL_BIN_INTEL_H
#define LMP_NSTENCIL_BIN_INTEL_H
#include "nstencil.h"
namespace LAMMPS_NS {
template<int HALF, int DIM_3D, int TRI>
class NStencilBinIntel : public NStencil {
public:
NStencilBinIntel(class LAMMPS *);
void create() override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -11,34 +11,44 @@
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "nstencil_half_bin_3d_tri.h"
#include "nstencil_ghost_bin_intel.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NStencilHalfBin3dTri::NStencilHalfBin3dTri(LAMMPS *lmp) : NStencil(lmp) {}
template<int DIM_3D>
NStencilGhostBinIntel<DIM_3D>::NStencilGhostBinIntel(LAMMPS *lmp) : NStencil(lmp)
{
xyzflag = 1;
}
/* ----------------------------------------------------------------------
create stencil based on bin geometry and cutoff
------------------------------------------------------------------------- */
void NStencilHalfBin3dTri::create()
template<int DIM_3D>
void NStencilGhostBinIntel<DIM_3D>::create()
{
int i, j, k;
// for triclinic, need to use full stencil in all dims
// not a half stencil in z
// b/c transforming orthog -> lambda -> orthog for ghost atoms
// with an added PBC offset can shift all 3 coords by epsilon
// thus for an I/J owned/ghost pair, the xyz coords
// and bin assignments can be different on I proc vs J proc
nstencil = 0;
for (k = -sz; k <= sz; k++)
for (j = -sy; j <= sy; j++)
for (i = -sx; i <= sx; i++)
if (bin_distance(i, j, k) < cutneighmaxsq)
for (k = -sz; k <= sz; k++) {
for (j = -sy; j <= sy; j++) {
for (i = -sx; i <= sx; i++) {
if (bin_distance(i, j, k) < cutneighmaxsq) {
stencilxyz[nstencil][0] = i;
stencilxyz[nstencil][1] = j;
stencilxyz[nstencil][2] = k;
stencil[nstencil++] = k * mbiny * mbinx + j * mbinx + i;
}
}
}
}
}
namespace LAMMPS_NS {
template class NStencilGhostBinIntel<0>;
template class NStencilGhostBinIntel<1>;
}

View File

@ -13,22 +13,29 @@
#ifdef NSTENCIL_CLASS
// clang-format off
NStencilStyle(full/ghost/bin/3d,
NStencilFullGhostBin3d,
NS_FULL | NS_GHOST | NS_BIN | NS_3D | NS_ORTHO | NS_TRI);
typedef NStencilGhostBinIntel<0> NStencilFullGhostBin2dIntel;
NStencilStyle(full/ghost/bin/2d/intel,
NStencilFullGhostBin2dIntel,
NS_FULL | NS_GHOST | NS_BIN | NS_2D | NS_ORTHO | NS_TRI | NS_INTEL);
typedef NStencilGhostBinIntel<1> NStencilFullGhostBin3dIntel;
NStencilStyle(full/ghost/bin/3d/intel,
NStencilFullGhostBin3dIntel,
NS_FULL | NS_GHOST | NS_BIN | NS_3D | NS_ORTHO | NS_TRI | NS_INTEL);
// clang-format on
#else
#ifndef LMP_NSTENCIL_FULL_GHOST_BIN_3D_H
#define LMP_NSTENCIL_FULL_GHOST_BIN_3D_H
#ifndef LMP_NSTENCIL_GHOST_BIN_INTEL_H
#define LMP_NSTENCIL_GHOST_BIN_INTEL_H
#include "nstencil.h"
namespace LAMMPS_NS {
class NStencilFullGhostBin3d : public NStencil {
template<int DIM_3D>
class NStencilGhostBinIntel : public NStencil {
public:
NStencilFullGhostBin3d(class LAMMPS *);
NStencilGhostBinIntel(class LAMMPS *);
void create() override;
};

View File

@ -165,6 +165,8 @@ action fix_qeq_reaxff_kokkos.cpp fix_qeq_reaxff.cpp
action fix_qeq_reaxff_kokkos.h fix_qeq_reaxff.h
action fix_reaxff_bonds_kokkos.cpp fix_reaxff_bonds.cpp
action fix_reaxff_bonds_kokkos.h fix_reaxff_bonds.h
action compute_reaxff_atom_kokkos.cpp compute_reaxff_atom.cpp
action compute_reaxff_atom_kokkos.h compute_reaxff_atom.h
action fix_reaxff_species_kokkos.cpp fix_reaxff_species.cpp
action fix_reaxff_species_kokkos.h fix_reaxff_species.h
action fix_rx_kokkos.cpp fix_rx.cpp

View File

@ -0,0 +1,195 @@
// 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.
------------------------------------------------------------------------- */
/* ----------------------------------------------------------------------
Contributing author: Richard Berger (LANL)
------------------------------------------------------------------------- */
#include "compute_reaxff_atom_kokkos.h"
#include "atom.h"
#include "molecule.h"
#include "update.h"
#include "force.h"
#include "memory.h"
#include "error.h"
#include "neigh_list.h"
#include "memory_kokkos.h"
#include "pair_reaxff_kokkos.h"
#include "reaxff_api.h"
using namespace LAMMPS_NS;
using namespace ReaxFF;
/* ---------------------------------------------------------------------- */
template<class DeviceType>
ComputeReaxFFAtomKokkos<DeviceType>::ComputeReaxFFAtomKokkos(LAMMPS *lmp, int narg, char **arg) :
ComputeReaxFFAtom(lmp, narg, arg),
nbuf(-1), buf(nullptr)
{
kokkosable = 1;
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
ComputeReaxFFAtomKokkos<DeviceType>::~ComputeReaxFFAtomKokkos()
{
memoryKK->destroy_kokkos(k_buf, buf);
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void ComputeReaxFFAtomKokkos<DeviceType>::init()
{
ComputeReaxFFAtom::init();
if (!reaxff || !reaxff->kokkosable) {
error->all(FLERR,"Cannot use compute reaxff/atom/kk without "
"pair_style reaxff/kk");
}
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void ComputeReaxFFAtomKokkos<DeviceType>::compute_bonds()
{
if (atom->nlocal > nlocal) {
memory->destroy(array_atom);
nlocal = atom->nlocal;
memory->create(array_atom, nlocal, 3, "reaxff/atom:array_atom");
}
// retrieve bond information from kokkos pair style. the data potentially
// lives on device. it is copied into buf on the host in a condensed format
// compute_local and compute_atom then expand the data from this buffer into
// appropiate arrays for consumption by others (e.g. dump local, dump custom
// or library interface)
int maxnumbonds = 0;
if (reaxff->execution_space == Device)
device_pair()->FindBond(maxnumbonds, groupbit);
else
host_pair()->FindBond(maxnumbonds, groupbit);
nbuf = ((store_bonds ? maxnumbonds*2 : 0) + 3)*nlocal;
if (!buf || k_buf.extent(0) < nbuf) {
memoryKK->destroy_kokkos(k_buf, buf);
memoryKK->create_kokkos(k_buf, buf, nbuf, "reaxff/atom:buf");
}
// Pass information to buffer, will sync to host
int nbuf_local;
if (reaxff->execution_space == Device)
device_pair()->PackReducedBondBuffer(k_buf, nbuf_local, store_bonds);
else
host_pair()->PackReducedBondBuffer(k_buf, nbuf_local, store_bonds);
// Extract number of bonds from buffer
nbonds = 0;
int j = 0;
for (int i = 0; i < nlocal; i++) {
int numbonds = static_cast<int>(buf[j+2]);
nbonds += numbonds;
j += (store_bonds ? 2*numbonds : 0) + 3;
}
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void ComputeReaxFFAtomKokkos<DeviceType>::compute_local()
{
invoked_local = update->ntimestep;
if (invoked_bonds < update->ntimestep)
compute_bonds();
if (nbonds > prev_nbonds) {
// grow array_local
memory->destroy(array_local);
memory->create(array_local, nbonds, 3, "reaxff/atom:array_local");
prev_nbonds = nbonds;
}
size_local_rows = nbonds;
// extract local bond information from buffer
int b = 0;
int j = 0;
auto tag = atom->tag;
for (int i = 0; i < nlocal; ++i) {
const int numbonds = static_cast<int>(buf[j+2]);
const int neigh_offset = j + 3;
const int bo_offset = neigh_offset + numbonds;
for (int k = 0; k < numbonds; k++) {
auto bond = array_local[b++];
bond[0] = tag[i];
bond[1] = static_cast<tagint> (buf[neigh_offset+k]);
bond[2] = buf[bo_offset+k];
}
j += 2*numbonds + 3;
}
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void ComputeReaxFFAtomKokkos<DeviceType>::compute_peratom()
{
invoked_peratom = update->ntimestep;
if (invoked_bonds < update->ntimestep)
compute_bonds();
// extract peratom bond information from buffer
int j = 0;
for (int i = 0; i < nlocal; ++i) {
auto ptr = array_atom[i];
int numbonds = static_cast<int>(buf[j+2]);
ptr[0] = buf[j]; // sbo
ptr[1] = buf[j+1]; // nlp
ptr[2] = numbonds;
j += (store_bonds ? 2*numbonds : 0) + 3;
}
}
/* ----------------------------------------------------------------------
memory usage of local data
------------------------------------------------------------------------- */
template<class DeviceType>
double ComputeReaxFFAtomKokkos<DeviceType>::memory_usage()
{
double bytes = (double)(nlocal*3) * sizeof(double);
if (store_bonds)
bytes += (double)(nbonds*3) * sizeof(double);
bytes += (double)(nbuf > 0 ? nbuf * sizeof(double) : 0);
return bytes;
}
namespace LAMMPS_NS {
template class ComputeReaxFFAtomKokkos<LMPDeviceType>;
#ifdef LMP_KOKKOS_GPU
template class ComputeReaxFFAtomKokkos<LMPHostType>;
#endif
}

View File

@ -0,0 +1,66 @@
/* -*- 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: Richard Berger (LANL)
------------------------------------------------------------------------- */
#ifdef COMPUTE_CLASS
// clang-format off
ComputeStyle(reaxff/atom/kk,ComputeReaxFFAtomKokkos<LMPDeviceType>);
ComputeStyle(reaxff/atom/kk/device,ComputeReaxFFAtomKokkos<LMPDeviceType>);
ComputeStyle(reaxff/atom/kk/host,ComputeReaxFFAtomKokkos<LMPHostType>);
// clang-format on
#else
#ifndef LMP_COMPUTE_REAXFF_BONDS_KOKKOS_H
#define LMP_COMPUTE_REAXFF_BONDS_KOKKOS_H
#include "compute_reaxff_atom.h"
#include "pair_reaxff_kokkos.h"
#include "kokkos_type.h"
namespace LAMMPS_NS {
template<class DeviceType>
class ComputeReaxFFAtomKokkos : public ComputeReaxFFAtom {
public:
using device_type = DeviceType;
using AT = ArrayTypes<DeviceType>;
ComputeReaxFFAtomKokkos(class LAMMPS *, int, char **);
~ComputeReaxFFAtomKokkos() override;
void init() override;
void compute_local() override;
void compute_peratom() override;
void compute_bonds() override;
double memory_usage() override;
private:
int nbuf;
double *buf;
typename AT::tdual_float_1d k_buf;
auto device_pair() {
return static_cast<PairReaxFFKokkos<LMPDeviceType>*>(reaxff);
}
auto host_pair() {
return static_cast<PairReaxFFKokkos<LMPHostType>*>(reaxff);
}
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -4162,22 +4162,23 @@ double PairReaxFFKokkos<DeviceType>::memory_usage()
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void PairReaxFFKokkos<DeviceType>::FindBond(int &numbonds)
void PairReaxFFKokkos<DeviceType>::FindBond(int &numbonds, int groupbit)
{
copymode = 1;
Kokkos::parallel_for(Kokkos::RangePolicy<DeviceType, TagPairReaxFindBondZero>(0,nmax),*this);
bo_cut_bond = api->control->bg_cut;
atomKK->sync(execution_space,TAG_MASK);
atomKK->sync(execution_space,TAG_MASK|MASK_MASK);
tag = atomKK->k_tag.view<DeviceType>();
mask = atomKK->k_mask.view<DeviceType>();
const int inum = list->inum;
NeighListKokkos<DeviceType>* k_list = static_cast<NeighListKokkos<DeviceType>*>(list);
d_ilist = k_list->d_ilist;
numbonds = 0;
PairReaxKokkosFindBondFunctor<DeviceType> find_bond_functor(this);
PairReaxKokkosFindBondFunctor<DeviceType> find_bond_functor(this, groupbit);
Kokkos::parallel_reduce(inum,find_bond_functor,numbonds);
copymode = 0;
}
@ -4194,24 +4195,28 @@ void PairReaxFFKokkos<DeviceType>::operator()(TagPairReaxFindBondZero, const int
template<class DeviceType>
KOKKOS_INLINE_FUNCTION
void PairReaxFFKokkos<DeviceType>::calculate_find_bond_item(int ii, int &numbonds) const
void PairReaxFFKokkos<DeviceType>::calculate_find_bond_item(int ii, int &numbonds, int groupbit) const
{
const int i = d_ilist[ii];
int nj = 0;
const int j_start = d_bo_first[i];
const int j_end = j_start + d_bo_num[i];
for (int jj = j_start; jj < j_end; jj++) {
int j = d_bo_list[jj];
j &= NEIGHMASK;
const tagint jtag = tag[j];
const int j_index = jj - j_start;
double bo_tmp = d_BO(i,j_index);
if (mask[i] & groupbit) {
const int j_start = d_bo_first[i];
const int j_end = j_start + d_bo_num[i];
for (int jj = j_start; jj < j_end; jj++) {
int j = d_bo_list[jj];
j &= NEIGHMASK;
if (mask[j] & groupbit) {
const tagint jtag = tag[j];
const int j_index = jj - j_start;
double bo_tmp = d_BO(i,j_index);
if (bo_tmp > bo_cut_bond) {
d_neighid(i,nj) = jtag;
d_abo(i,nj) = bo_tmp;
nj++;
if (bo_tmp > bo_cut_bond) {
d_neighid(i,nj) = jtag;
d_abo(i,nj) = bo_tmp;
nj++;
}
}
}
}
d_numneigh_bonds[i] = nj;
@ -4247,6 +4252,36 @@ void PairReaxFFKokkos<DeviceType>::PackBondBuffer(DAT::tdual_ffloat_1d k_buf, in
nbuf_local = k_nbuf_local.h_view();
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
void PairReaxFFKokkos<DeviceType>::PackReducedBondBuffer(DAT::tdual_ffloat_1d k_buf, int &nbuf_local, bool store_bonds)
{
d_buf = k_buf.view<DeviceType>();
k_params_sing.template sync<DeviceType>();
copymode = 1;
nlocal = atomKK->nlocal;
if (store_bonds) {
PairReaxKokkosPackReducedBondBufferFunctor<DeviceType, true> pack_bond_buffer_functor(this);
Kokkos::parallel_scan(nlocal,pack_bond_buffer_functor);
} else {
PairReaxKokkosPackReducedBondBufferFunctor<DeviceType, false> pack_bond_buffer_functor(this);
Kokkos::parallel_scan(nlocal,pack_bond_buffer_functor);
}
copymode = 0;
k_buf.modify<DeviceType>();
k_nbuf_local.modify<DeviceType>();
k_buf.sync<LMPHostType>();
k_nbuf_local.sync<LMPHostType>();
nbuf_local = k_nbuf_local.h_view();
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>
KOKKOS_INLINE_FUNCTION
void PairReaxFFKokkos<DeviceType>::pack_bond_buffer_item(int i, int &j, const bool &final) const
@ -4288,6 +4323,42 @@ void PairReaxFFKokkos<DeviceType>::pack_bond_buffer_item(int i, int &j, const bo
k_nbuf_local.view<DeviceType>()() = j - 1;
}
template<class DeviceType>
template<bool STORE_BONDS>
KOKKOS_INLINE_FUNCTION
void PairReaxFFKokkos<DeviceType>::pack_reduced_bond_buffer_item(int i, int &j, const bool &final) const
{
const int numbonds = d_numneigh_bonds[i];
if (final) {
d_buf[j] = d_total_bo[i];
d_buf[j+1] = paramssing(type[i]).nlp_opt - d_Delta_lp[i];
d_buf[j+2] = numbonds;
}
j += 3;
if constexpr(STORE_BONDS) {
if (final) {
for (int k = 0; k < numbonds; ++k) {
d_buf[j+k] = d_neighid(i,k);
}
}
j += numbonds;
if (final) {
for (int k = 0; k < numbonds; k++) {
d_buf[j+k] = d_abo(i,k);
}
}
j += numbonds;
}
if (final && i == nlocal-1)
k_nbuf_local.view<DeviceType>()() = j - 1;
}
/* ---------------------------------------------------------------------- */
template<class DeviceType>

View File

@ -130,8 +130,9 @@ class PairReaxFFKokkos : public PairReaxFF {
void compute(int, int);
void init_style();
double memory_usage();
void FindBond(int &);
void FindBond(int &, int groupbit = 1);
void PackBondBuffer(DAT::tdual_ffloat_1d, int &);
void PackReducedBondBuffer(DAT::tdual_ffloat_1d, int &, bool);
void FindBondSpecies();
template<int NEIGHFLAG>
@ -284,11 +285,15 @@ class PairReaxFFKokkos : public PairReaxFF {
void operator()(TagPairReaxFindBondZero, const int&) const;
KOKKOS_INLINE_FUNCTION
void calculate_find_bond_item(int, int&) const;
void calculate_find_bond_item(int, int&, int) const;
KOKKOS_INLINE_FUNCTION
void pack_bond_buffer_item(int, int&, const bool&) const;
template<bool STORE_BONDS>
KOKKOS_INLINE_FUNCTION
void pack_reduced_bond_buffer_item(int, int&, const bool&) const;
KOKKOS_INLINE_FUNCTION
void operator()(TagPairReaxFindBondSpeciesZero, const int&) const;
@ -409,6 +414,7 @@ class PairReaxFFKokkos : public PairReaxFF {
typename AT::t_f_array f;
typename AT::t_int_1d_randomread type;
typename AT::t_tagint_1d_randomread tag;
typename AT::t_int_1d_randomread mask;
typename AT::t_float_1d_randomread q;
typename AT::t_tagint_1d_randomread molecule;
@ -518,8 +524,9 @@ template <class DeviceType>
struct PairReaxKokkosFindBondFunctor {
typedef DeviceType device_type;
typedef int value_type;
int groupbit;
PairReaxFFKokkos<DeviceType> c;
PairReaxKokkosFindBondFunctor(PairReaxFFKokkos<DeviceType>* c_ptr):c(*c_ptr) {};
PairReaxKokkosFindBondFunctor(PairReaxFFKokkos<DeviceType>* c_ptr, int groupbit):c(*c_ptr),groupbit(groupbit) {};
KOKKOS_INLINE_FUNCTION
void join(int &dst,
@ -529,7 +536,7 @@ struct PairReaxKokkosFindBondFunctor {
KOKKOS_INLINE_FUNCTION
void operator()(const int ii, int &numbonds) const {
c.calculate_find_bond_item(ii,numbonds);
c.calculate_find_bond_item(ii,numbonds,groupbit);
}
};
@ -546,6 +553,19 @@ struct PairReaxKokkosPackBondBufferFunctor {
}
};
template <class DeviceType, bool STORE_BONDS>
struct PairReaxKokkosPackReducedBondBufferFunctor {
typedef DeviceType device_type;
typedef int value_type;
PairReaxFFKokkos<DeviceType> c;
PairReaxKokkosPackReducedBondBufferFunctor(PairReaxFFKokkos<DeviceType>* c_ptr):c(*c_ptr) {};
KOKKOS_INLINE_FUNCTION
void operator()(const int ii, int &j, const bool &final) const {
c.template pack_reduced_bond_buffer_item<STORE_BONDS>(ii,j,final);
}
};
}
#endif

View File

@ -12,30 +12,41 @@
See the README file in the top-level LAMMPS directory.
------------------------------------------------------------------------- */
#include "omp_compat.h"
#include "npair_full_bin_ghost_omp.h"
#include "npair_bin_ghost_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "omp_compat.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
#include "molecule.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairFullBinGhostOmp::NPairFullBinGhostOmp(LAMMPS *lmp) : NPair(lmp) {}
template<int HALF>
NPairBinGhostOmp<HALF>::NPairBinGhostOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction for all neighbors
include neighbors of ghost atoms, but no "special neighbors" for ghosts
every neighbor pair appears in list of both atoms i and j
Full:
binned neighbor list construction for all neighbors
include neighbors of ghost atoms, but no "special neighbors" for ghosts
every neighbor pair appears in list of both atoms i and j
Half + Newtoff:
binned neighbor list construction with partial Newton's 3rd law
include neighbors of ghost atoms, but no "special neighbors" for ghosts
owned and ghost atoms check own bin and other bins in stencil
pair stored once if i,j are both owned and i < j
pair stored by me if i owned and j ghost (also stored by proc owning j)
pair stored once if i,j are both ghost and i < j
------------------------------------------------------------------------- */
void NPairFullBinGhostOmp::build(NeighList *list)
template<int HALF>
void NPairBinGhostOmp<HALF>::build(NeighList *list)
{
const int nlocal = atom->nlocal;
const int nall = nlocal + atom->nghost;
@ -48,10 +59,10 @@ void NPairFullBinGhostOmp::build(NeighList *list)
#endif
NPAIR_OMP_SETUP(nall);
int i,j,k,n,itype,jtype,ibin,which,imol,iatom;
int i, j, k, n, itype, jtype, ibin, bin_start, which, imol, iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int xbin,ybin,zbin,xbin2,ybin2,zbin2;
double xtmp, ytmp, ztmp, delx, dely, delz, rsq;
int xbin, ybin, zbin, xbin2, ybin2, zbin2;
int *neighptr;
double **x = atom->x;
@ -93,43 +104,56 @@ void NPairFullBinGhostOmp::build(NeighList *list)
// loop over all atoms in surrounding bins in stencil including self
// when i is a ghost atom, must check if stencil bin is out of bounds
// skip i = j
// no molecular test when i = ghost atom
if (i < nlocal) {
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (i == j) continue;
for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) {
if (HALF) {
// Half neighbor list, newton off
// only store pair if i < j
// stores own/own pairs only once
// stores own/ghost pairs on both procs
// stores ghost/ghost pairs only once
if (j <= i) continue;
} else {
// Full neighbor list
// only skip i = j
if (i == j) continue;
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
rsq = delx * delx + dely * dely + delz * delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
which = find_special(special[i], nspecial[i], tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom],
tag[j] - tagprev);
else
which = 0;
if (which == 0)
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
else if (domain->minimum_image_check(delx, dely, delz))
neighptr[n++] = j;
else if (which > 0)
neighptr[n++] = j ^ (which << SBBITS);
} else
neighptr[n++] = j;
}
}
}
} else {
ibin = coord2bin(x[i],xbin,ybin,zbin);
ibin = coord2bin(x[i], xbin, ybin, zbin);
for (k = 0; k < nstencil; k++) {
xbin2 = xbin + stencilxyz[k][0];
ybin2 = ybin + stencilxyz[k][1];
@ -137,16 +161,20 @@ void NPairFullBinGhostOmp::build(NeighList *list)
if (xbin2 < 0 || xbin2 >= mbinx ||
ybin2 < 0 || ybin2 >= mbiny ||
zbin2 < 0 || zbin2 >= mbinz) continue;
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (i == j) continue;
for (j = binhead[ibin + stencil[k]]; j >= 0; j = bins[j]) {
if (HALF) {
if (j <= i) continue;
} else {
if (i == j) continue;
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
rsq = delx * delx + dely * dely + delz * delz;
if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j;
}
@ -157,10 +185,14 @@ void NPairFullBinGhostOmp::build(NeighList *list)
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->gnum = nall - nlocal;
}
namespace LAMMPS_NS {
template class NPairBinGhostOmp<0>;
template class NPairBinGhostOmp<1>;
}

View File

@ -13,23 +13,29 @@
#ifdef NPAIR_CLASS
// clang-format off
typedef NPairBinGhostOmp<0> NPairFullBinGhostOmp;
NPairStyle(full/bin/ghost/omp,
NPairFullBinGhostOmp,
NP_FULL | NP_BIN | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF |
NP_ORTHO | NP_TRI);
NP_FULL | NP_BIN | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinGhostOmp<1> NPairHalfBinNewtoffGhostOmp;
NPairStyle(half/bin/newtoff/ghost/omp,
NPairHalfBinNewtoffGhostOmp,
NP_HALF | NP_BIN | NP_GHOST | NP_OMP | NP_NEWTOFF | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_BIN_GHOST_OMP_H
#define LMP_NPAIR_FULL_BIN_GHOST_OMP_H
#ifndef LMP_NPAIR_BIN_GHOST_OMP_H
#define LMP_NPAIR_BIN_GHOST_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairFullBinGhostOmp : public NPair {
template<int HALF>
class NPairBinGhostOmp : public NPair {
public:
NPairFullBinGhostOmp(class LAMMPS *);
NPairBinGhostOmp(class LAMMPS *);
void build(class NeighList *) override;
};

View File

@ -0,0 +1,277 @@
// 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 "npair_bin_omp.h"
#include "npair_omp.h"
#include "omp_compat.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "molecule.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
NPairBinOmp<HALF, NEWTON, TRI, SIZE, ATOMONLY>::NPairBinOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
Full:
binned neighbor list construction for all neighbors
every neighbor pair appears in list of both atoms i and j
Half + Newtoff:
binned neighbor list construction with partial Newton's 3rd law
each owned atom i checks own bin and other bins in stencil
pair stored once if i,j are both owned and i < j
pair stored by me if j is ghost (also stored by proc owning j)
Half + Newton:
binned neighbor list construction with full Newton's 3rd law
each owned atom i checks its own bin and other bins in Newton stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
void NPairBinOmp<HALF, NEWTON, TRI, SIZE, ATOMONLY>::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
const double delta = 0.01 * force->angstrom;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i, j, jh, k, n, itype, jtype, ibin, bin_start, which, imol, iatom;
tagint itag, jtag, tagprev;
double xtmp, ytmp, ztmp, delx, dely, delz, rsq, radsum, cut, cutsq;
int *neighptr;
double **x = atom->x;
double *radius = atom->radius;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int history = list->history;
int mask_history = 1 << HISTBITS;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itag = tag[i];
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (!ATOMONLY) {
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
}
// loop over all atoms in surrounding bins in stencil including self
// skip i = j
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
bin_start = binhead[ibin + stencil[k]];
if (HALF && NEWTON && (!TRI)) {
if (k == 0) {
// Half neighbor list, newton on, orthonormal
// loop over rest of atoms in i's bin, ghosts are at end of linked list
bin_start = bins[i];
}
}
for (j = bin_start; j >= 0; j = bins[j]) {
if (!HALF) {
// Full neighbor list
// only skip i = j
if (i == j) continue;
} else if (!NEWTON) {
// Half neighbor list, newton off
// only store pair if i < j
// stores own/own pairs only once
// stores own/ghost pairs on both procs
if (j <= i) continue;
} else if (TRI) {
// Half neighbor list, newton on, triclinic
// for triclinic, bin stencil is full in all 3 dims
// must use itag/jtag to eliminate half the I/J interactions
// cannot use I/J exact coord comparision
// b/c transforming orthog -> lambda -> orthog for ghost atoms
// with an added PBC offset can shift all 3 coords by epsilon
if (j <= i) continue;
if (j >= nlocal) {
jtag = tag[j];
if (itag > jtag) {
if ((itag + jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag + jtag) % 2 == 1) continue;
} else {
if (fabs(x[j][2] - ztmp) > delta) {
if (x[j][2] < ztmp) continue;
} else if (fabs(x[j][1] - ytmp) > delta) {
if (x[j][1] < ytmp) continue;
} else {
if (x[j][0] < xtmp) continue;
}
}
}
} else {
// Half neighbor list, newton on, orthonormal
// store every pair for every bin in stencil, except for i's bin
if (k == 0) {
// if j is owned atom, store it, since j is beyond i in linked list
// if j is ghost, only store if j coords are "above and to the "right" of i
if (j >= nlocal) {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp) {
if (x[j][1] < ytmp) continue;
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
}
}
}
jtype = type[j];
if (exclude && exclusion(i, j, itype, jtype, mask, molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx * delx + dely * dely + delz * delz;
if (SIZE) {
radsum = radius[i] + radius[j];
cut = radsum + skin;
cutsq = cut * cut;
if (ATOMONLY) {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
jh = jh ^ mask_history;
neighptr[n++] = jh;
}
} else {
if (rsq <= cutsq) {
jh = j;
if (history && rsq < radsum * radsum)
jh = jh ^ mask_history;
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i], nspecial[i], tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom], onemols[imol] ->nspecial[iatom],
tag[j] - tagprev);
else
which = 0;
if (which == 0)
neighptr[n++] = jh;
else if (domain->minimum_image_check(delx, dely, delz))
neighptr[n++] = jh;
else if (which > 0)
neighptr[n++] = jh ^ (which << SBBITS);
} else
neighptr[n++] = jh;
}
}
} else {
if (ATOMONLY) {
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
} else {
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i], nspecial[i], tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom], onemols[imol]->nspecial[iatom],
tag[j] - tagprev);
else which = 0;
if (which == 0)
neighptr[n++] = j;
else if (domain->minimum_image_check(delx, dely, delz))
neighptr[n++] = j;
else if (which > 0)
neighptr[n++] = j ^ (which << SBBITS);
} else
neighptr[n++] = j;
}
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status()) error->one(FLERR, "Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
if (!HALF) list->gnum = 0;
}
namespace LAMMPS_NS {
template class NPairBinOmp<0,1,0,0,0>;
template class NPairBinOmp<1,0,0,0,0>;
template class NPairBinOmp<1,1,0,0,0>;
template class NPairBinOmp<1,1,1,0,0>;
template class NPairBinOmp<0,1,0,1,0>;
template class NPairBinOmp<1,0,0,1,0>;
template class NPairBinOmp<1,1,0,1,0>;
template class NPairBinOmp<1,1,1,1,0>;
template class NPairBinOmp<0,1,0,0,1>;
template class NPairBinOmp<1,0,0,0,1>;
template class NPairBinOmp<1,1,0,0,1>;
template class NPairBinOmp<1,1,1,0,1>;
template class NPairBinOmp<0,1,0,1,1>;
template class NPairBinOmp<1,0,0,1,1>;
template class NPairBinOmp<1,1,0,1,1>;
template class NPairBinOmp<1,1,1,1,1>;
}

119
src/OPENMP/npair_bin_omp.h Normal file
View File

@ -0,0 +1,119 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
typedef NPairBinOmp<0, 1, 0, 0, 0> NPairFullBinOmp;
NPairStyle(full/bin/omp,
NPairFullBinOmp,
NP_FULL | NP_BIN | NP_OMP | NP_MOLONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 0, 0> NPairHalfBinNewtoffOmp;
NPairStyle(half/bin/newtoff/omp,
NPairHalfBinNewtoffOmp,
NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 0, 0> NPairHalfBinNewtonOmp;
NPairStyle(half/bin/newton/omp,
NPairHalfBinNewtonOmp,
NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 0, 0> NPairHalfBinNewtonTriOmp;
NPairStyle(half/bin/newton/tri/omp,
NPairHalfBinNewtonTriOmp,
NP_HALF | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairBinOmp<0, 1, 0, 1, 0> NPairFullSizeBinOmp;
NPairStyle(full/size/bin/omp,
NPairFullSizeBinOmp,
NP_FULL | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 1, 0> NPairHalfSizeBinNewtoffOmp;
NPairStyle(half/size/bin/newtoff/omp,
NPairHalfSizeBinNewtoffOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 1, 0> NPairHalfSizeBinNewtonOmp;
NPairStyle(half/size/bin/newton/omp,
NPairHalfSizeBinNewtonOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 1, 0> NPairHalfSizeBinNewtonTriOmp;
NPairStyle(half/size/bin/newton/tri/omp,
NPairHalfSizeBinNewtonTriOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_MOLONLY | NP_NEWTON | NP_TRI);
typedef NPairBinOmp<0, 1, 0, 0, 1> NPairFullBinAtomonlyOmp;
NPairStyle(full/bin/atomonly/omp,
NPairFullBinAtomonlyOmp,
NP_FULL | NP_BIN | NP_OMP | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 0, 1> NPairHalfBinNewtoffAtomonlyOmp;
NPairStyle(half/bin/newtoff/atomonly/omp,
NPairHalfBinNewtoffAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 0, 1> NPairHalfBinNewtonAtomonlyOmp;
NPairStyle(half/bin/newton/atomonly/omp,
NPairHalfBinNewtonAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 0, 1> NPairHalfBinNewtonTriAtomonlyOmp;
NPairStyle(half/bin/newton/tri/atomonly/omp,
NPairHalfBinNewtonTriAtomonlyOmp,
NP_HALF | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI);
typedef NPairBinOmp<0, 1, 0, 1, 1> NPairFullSizeBinAtomonlyOmp;
NPairStyle(full/size/bin/atomonly/omp,
NPairFullSizeBinAtomonlyOmp,
NP_FULL | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 0, 0, 1, 1> NPairHalfSizeBinNewtoffAtomonlyOmp;
NPairStyle(half/size/bin/newtoff/atomonly/omp,
NPairHalfSizeBinNewtoffAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTOFF | NP_ORTHO | NP_TRI);
typedef NPairBinOmp<1, 1, 0, 1, 1> NPairHalfSizeBinNewtonAtomonlyOmp;
NPairStyle(half/size/bin/newton/atomonly/omp,
NPairHalfSizeBinNewtonAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_ORTHO);
typedef NPairBinOmp<1, 1, 1, 1, 1> NPairHalfSizeBinNewtonTriAtomonlyOmp;
NPairStyle(half/size/bin/newton/tri/atomonly/omp,
NPairHalfSizeBinNewtonTriAtomonlyOmp,
NP_HALF | NP_SIZE | NP_BIN | NP_OMP | NP_ATOMONLY | NP_NEWTON | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_BIN_OMP_H
#define LMP_NPAIR_BIN_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
template<int HALF, int NEWTON, int TRI, int SIZE, int ATOMONLY>
class NPairBinOmp : public NPair {
public:
NPairBinOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,106 +0,0 @@
// 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 "npair_full_bin_atomonly_omp.h"
#include "atom.h"
#include "error.h"
#include "my_page.h"
#include "neigh_list.h"
#include "npair_omp.h"
#include "omp_compat.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairFullBinAtomonlyOmp::NPairFullBinAtomonlyOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction for all neighbors
every neighbor pair appears in list of both atoms i and j
------------------------------------------------------------------------- */
void NPairFullBinAtomonlyOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *molecule = atom->molecule;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
// loop over all atoms in surrounding bins in stencil including self
// skip i = j
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (i == j) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->gnum = 0;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(full/bin/atomonly/omp,
NPairFullBinAtomonlyOmp,
NP_FULL | NP_BIN | NP_ATOMONLY | NP_OMP |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_BIN_ATOMONLY_OMP_H
#define LMP_NPAIR_FULL_BIN_ATOMONLY_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairFullBinAtomonlyOmp : public NPair {
public:
NPairFullBinAtomonlyOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,135 +0,0 @@
// 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 "omp_compat.h"
#include "npair_full_bin_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairFullBinOmp::NPairFullBinOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction for all neighbors
every neighbor pair appears in list of both atoms i and j
------------------------------------------------------------------------- */
void NPairFullBinOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms in surrounding bins in stencil including self
// skip i = j
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (i == j) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->gnum = 0;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(full/bin/omp,
NPairFullBinOmp,
NP_FULL | NP_BIN | NP_OMP | NP_NEWTON | NP_NEWTOFF |
NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_BIN_OMP_H
#define LMP_NPAIR_FULL_BIN_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairFullBinOmp : public NPair {
public:
NPairFullBinOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(full/multi/old/omp,
NPairFullMultiOldOmp,
NP_FULL | NP_MULTI_OLD | NP_OMP |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_MULTI_OLD_OMP_H
#define LMP_NPAIR_FULL_MULTI_OLD_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairFullMultiOldOmp : public NPair {
public:
NPairFullMultiOldOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,154 +0,0 @@
// 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 "omp_compat.h"
#include "npair_full_multi_omp.h"
#include "npair_omp.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairFullMultiOmp::NPairFullMultiOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction for all neighbors
multi stencil is icollection-jcollection dependent
every neighbor pair appears in list of both atoms i and j
------------------------------------------------------------------------- */
void NPairFullMultiOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
int js;
// loop over each atom, storing neighbors
int *collection = neighbor->collection;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
icollection = collection[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
ibin = atom2bin[i];
// loop through stencils for all collections
for (jcollection = 0; jcollection < ncollections; jcollection++) {
// if same collection use own bin
if (icollection == jcollection) jbin = ibin;
else jbin = coord2bin(x[i], jcollection);
// loop over all atoms in surrounding bins in stencil including self
// skip i = j
// use full stencil for all collection combinations
s = stencil_multi[icollection][jcollection];
ns = nstencil_multi[icollection][jcollection];
for (k = 0; k < ns; k++) {
js = binhead_multi[jcollection][jbin + s[k]];
for (j = js; j >= 0; j = bins[j]) {
if (i == j) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->gnum = 0;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(full/multi/omp,
NPairFullMultiOmp,
NP_FULL | NP_MULTI | NP_OMP |
NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_MULTI_OMP_H
#define LMP_NPAIR_FULL_MULTI_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairFullMultiOmp : public NPair {
public:
NPairFullMultiOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,148 +0,0 @@
// 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 "omp_compat.h"
#include "npair_full_nsq_ghost_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairFullNsqGhostOmp::NPairFullNsqGhostOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
N^2 search for all neighbors
include neighbors of ghost atoms, but no "special neighbors" for ghosts
every neighbor pair appears in list of both atoms i and j
------------------------------------------------------------------------- */
void NPairFullNsqGhostOmp::build(NeighList *list)
{
const int nlocal = atom->nlocal;
const int nall = nlocal + atom->nghost;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nall);
int i,j,n,itype,jtype,which,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned & ghost atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms, owned and ghost
// skip i = j
// no molecular test when i = ghost atom
if (i < nlocal) {
for (j = 0; j < nall; j++) {
if (i == j) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
} else {
for (j = 0; j < nall; j++) {
if (i == j) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j;
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->gnum = nall - nlocal;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(full/nsq/ghost/omp,
NPairFullNsqGhostOmp,
NP_FULL | NP_NSQ | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF |
NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_NSQ_GHOST_OMP_H
#define LMP_NPAIR_FULL_NSQ_GHOST_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairFullNsqGhostOmp : public NPair {
public:
NPairFullNsqGhostOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,134 +0,0 @@
// 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 "omp_compat.h"
#include "npair_full_nsq_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "group.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairFullNsqOmp::NPairFullNsqOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
N^2 search for all neighbors
every neighbor pair appears in list of both atoms i and j
------------------------------------------------------------------------- */
void NPairFullNsqOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,n,itype,jtype,which,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int nall = atom->nlocal + atom->nghost;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms, owned and ghost
// skip i = j
for (j = 0; j < nall; j++) {
if (includegroup && !(mask[j] & bitmask)) continue;
if (i == j) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->gnum = 0;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(full/nsq/omp,
NPairFullNsqOmp,
NP_FULL | NP_NSQ | NP_OMP | NP_NEWTON | NP_NEWTOFF |
NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_FULL_NSQ_OMP_H
#define LMP_NPAIR_FULL_NSQ_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairFullNsqOmp : public NPair {
public:
NPairFullNsqOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,126 +0,0 @@
// 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 "npair_half_bin_atomonly_newton_omp.h"
#include "atom.h"
#include "error.h"
#include "my_page.h"
#include "neigh_list.h"
#include "npair_omp.h"
#include "omp_compat.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinAtomonlyNewtonOmp::NPairHalfBinAtomonlyNewtonOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with full Newton's 3rd law
each owned atom i checks its own bin and other bins in Newton stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfBinAtomonlyNewtonOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *molecule = atom->molecule;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
// loop over rest of atoms in i's bin, ghosts are at end of linked list
// if j is owned atom, store it, since j is beyond i in linked list
// if j is ghost, only store if j coords are "above and to the right" of i
for (j = bins[i]; j >= 0; j = bins[j]) {
if (j >= nlocal) {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp) {
if (x[j][1] < ytmp) continue;
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
}
// loop over all atoms in other bins in stencil, store every pair
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/bin/atomonly/newton/omp,
NPairHalfBinAtomonlyNewtonOmp,
NP_HALF | NP_BIN | NP_ATOMONLY | NP_NEWTON | NP_OMP | NP_ORTHO);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_BIN_ATOMONLY_NEWTON_OMP_H
#define LMP_NPAIR_HALF_BIN_ATOMONLY_NEWTON_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfBinAtomonlyNewtonOmp : public NPair {
public:
NPairHalfBinAtomonlyNewtonOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,174 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_bin_newtoff_ghost_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtoffGhostOmp::NPairHalfBinNewtoffGhostOmp(LAMMPS *lmp) :
NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with partial Newton's 3rd law
include neighbors of ghost atoms, but no "special neighbors" for ghosts
owned and ghost atoms check own bin and other bins in stencil
pair stored once if i,j are both owned and i < j
pair stored by me if i owned and j ghost (also stored by proc owning j)
pair stored once if i,j are both ghost and i < j
------------------------------------------------------------------------- */
void NPairHalfBinNewtoffGhostOmp::build(NeighList *list)
{
const int nlocal = atom->nlocal;
const int nall = nlocal + atom->nghost;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nall);
int i,j,k,n,itype,jtype,ibin,which,imol,iatom;
tagint tagprev;
int xbin,ybin,zbin,xbin2,ybin2,zbin2;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms in other bins in stencil including self
// when i is a ghost atom, must check if stencil bin is out of bounds
// only store pair if i < j
// stores own/own pairs only once
// stores own/ghost pairs with owned atom only, on both procs
// stores ghost/ghost pairs only once
// no molecular test when i = ghost atom
if (i < nlocal) {
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (j <= i) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
} else {
ibin = coord2bin(x[i],xbin,ybin,zbin);
for (k = 0; k < nstencil; k++) {
xbin2 = xbin + stencilxyz[k][0];
ybin2 = ybin + stencilxyz[k][1];
zbin2 = zbin + stencilxyz[k][2];
if (xbin2 < 0 || xbin2 >= mbinx ||
ybin2 < 0 || ybin2 >= mbiny ||
zbin2 < 0 || zbin2 >= mbinz) continue;
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (j <= i) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighghostsq[itype][jtype]) neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->gnum = nall - atom->nlocal;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/bin/newtoff/ghost/omp,
NPairHalfBinNewtoffGhostOmp,
NP_HALF | NP_BIN | NP_NEWTOFF | NP_GHOST | NP_OMP |
NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_OMP_H
#define LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfBinNewtoffGhostOmp : public NPair {
public:
NPairHalfBinNewtoffGhostOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,139 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_bin_newtoff_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtoffOmp::NPairHalfBinNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with partial Newton's 3rd law
each owned atom i checks own bin and other bins in stencil
pair stored once if i,j are both owned and i < j
pair stored by me if j is ghost (also stored by proc owning j)
------------------------------------------------------------------------- */
void NPairHalfBinNewtoffOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms in other bins in stencil including self
// only store pair if i < j
// stores own/own pairs only once
// stores own/ghost pairs on both procs
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (j <= i) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/bin/newtoff/omp,
NPairHalfBinNewtoffOmp,
NP_HALF | NP_BIN | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_OMP_H
#define LMP_NPAIR_HALF_BIN_NEWTOFF_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfBinNewtoffOmp : public NPair {
public:
NPairHalfBinNewtoffOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,172 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_bin_newton_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtonOmp::NPairHalfBinNewtonOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with full Newton's 3rd law
each owned atom i checks its own bin and other bins in Newton stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfBinNewtonOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over rest of atoms in i's bin, ghosts are at end of linked list
// if j is owned atom, store it, since j is beyond i in linked list
// if j is ghost, only store if j coords are "above and to the right" of i
for (j = bins[i]; j >= 0; j = bins[j]) {
if (j >= nlocal) {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp) {
if (x[j][1] < ytmp) continue;
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
// OLD: if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
// loop over all atoms in other bins in stencil, store every pair
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
// OLD: if (which >= 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/bin/newton/omp,
NPairHalfBinNewtonOmp,
NP_HALF | NP_BIN | NP_NEWTON | NP_OMP | NP_ORTHO);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_BIN_NEWTON_OMP_H
#define LMP_NPAIR_HALF_BIN_NEWTON_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfBinNewtonOmp : public NPair {
public:
NPairHalfBinNewtonOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,158 +0,0 @@
// 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 "npair_half_bin_newton_tri_omp.h"
#include "npair_omp.h"
#include "omp_compat.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "molecule.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfBinNewtonTriOmp::NPairHalfBinNewtonTriOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with Newton's 3rd law for triclinic
each owned atom i checks its own bin and other bins in triclinic stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfBinNewtonTriOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
const double delta = 0.01 * force->angstrom;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,imol,iatom;
tagint itag,jtag,tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itag = tag[i];
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms in bins in stencil
// for triclinic, bin stencil is full in all 3 dims
// must use itag/jtag to eliminate half the I/J interactions
// cannot use I/J exact coord comparision
// b/c transforming orthog -> lambda -> orthog for ghost atoms
// with an added PBC offset can shift all 3 coords by epsilon
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (j <= i) continue;
if (j >= nlocal) {
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (fabs(x[j][2]-ztmp) > delta) {
if (x[j][2] < ztmp) continue;
} else if (fabs(x[j][1]-ytmp) > delta) {
if (x[j][1] < ytmp) continue;
} else {
if (x[j][0] < xtmp) continue;
}
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/bin/newton/tri/omp,
NPairHalfBinNewtonTriOmp,
NP_HALF | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_BIN_NEWTON_TRI_OMP_H
#define LMP_NPAIR_HALF_BIN_NEWTON_TRI_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfBinNewtonTriOmp : public NPair {
public:
NPairHalfBinNewtonTriOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,157 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_multi_newtoff_omp.h"
#include "npair_omp.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfMultiNewtoffOmp::NPairHalfMultiNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with partial Newton's 3rd law
multi stencil is icollection-jcollection dependent
each owned atom i checks own bin and other bins in stencil
pair stored once if i,j are both owned and i < j
pair stored by me if j is ghost (also stored by proc owning j)
------------------------------------------------------------------------- */
void NPairHalfMultiNewtoffOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
int js;
// loop over each atom, storing neighbors
int *collection = neighbor->collection;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
icollection = collection[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
ibin = atom2bin[i];
// loop through stencils for all collections
for (jcollection = 0; jcollection < ncollections; jcollection++) {
// if same collection use own bin
if (icollection == jcollection) jbin = ibin;
else jbin = coord2bin(x[i], jcollection);
// loop over all atoms in other bins in stencil including self
// only store pair if i < j
// stores own/own pairs only once
// stores own/ghost pairs on both procs
// use full stencil for all collection combinations
s = stencil_multi[icollection][jcollection];
ns = nstencil_multi[icollection][jcollection];
for (k = 0; k < ns; k++) {
js = binhead_multi[jcollection][jbin + s[k]];
for (j = js; j >= 0; j = bins[j]) {
if (j <= i) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/multi/newtoff/omp,
NPairHalfMultiNewtoffOmp,
NP_HALF | NP_MULTI | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_MULTI_NEWTOFF_OMP_H
#define LMP_NPAIR_HALF_MULTI_NEWTOFF_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfMultiNewtoffOmp : public NPair {
public:
NPairHalfMultiNewtoffOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,205 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_multi_newton_omp.h"
#include "npair_omp.h"
#include "neighbor.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfMultiNewtonOmp::NPairHalfMultiNewtonOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with full Newton's 3rd law
multi stencil is icollection-jcollection dependent
each owned atom i checks its own bin and other bins in Newton stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfMultiNewtonOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,icollection,jcollection,ibin,jbin,which,ns,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
int js;
// loop over each atom, storing neighbors
int *collection = neighbor->collection;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
icollection = collection[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
ibin = atom2bin[i];
// loop through stencils for all collections
for (jcollection = 0; jcollection < ncollections; jcollection++) {
// if same collection use own bin
if (icollection == jcollection) jbin = ibin;
else jbin = coord2bin(x[i], jcollection);
// if same size: uses half stencil so check central bin
if (cutcollectionsq[icollection][icollection] == cutcollectionsq[jcollection][jcollection]){
if (icollection == jcollection) js = bins[i];
else js = binhead_multi[jcollection][jbin];
// if same collection,
// if j is owned atom, store it, since j is beyond i in linked list
// if j is ghost, only store if j coords are "above and to the right" of i
// if different collections,
// if j is owned atom, store it if j > i
// if j is ghost, only store if j coords are "above and to the right" of i
for (j = js; j >= 0; j = bins[j]) {
if ((icollection != jcollection) && (j < i)) continue;
if (j >= nlocal) {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp) {
if (x[j][1] < ytmp) continue;
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
// for all collections, loop over all atoms in other bins in stencil, store every pair
// stencil is empty if i larger than j
// stencil is half if i same size as j
// stencil is full if i smaller than j
s = stencil_multi[icollection][jcollection];
ns = nstencil_multi[icollection][jcollection];
for (k = 0; k < ns; k++) {
js = binhead_multi[jcollection][jbin + s[k]];
for (j = js; j >= 0; j = bins[j]) {
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/multi/newton/omp,
NPairHalfMultiNewtonOmp,
NP_HALF | NP_MULTI | NP_NEWTON | NP_OMP | NP_ORTHO);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_OMP_H
#define LMP_NPAIR_HALF_MULTI_NEWTON_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfMultiNewtonOmp : public NPair {
public:
NPairHalfMultiNewtonOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,188 +0,0 @@
// 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 "npair_half_multi_newton_tri_omp.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "molecule.h"
#include "my_page.h"
#include "neigh_list.h"
#include "neighbor.h"
#include "npair_omp.h"
#include "omp_compat.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfMultiNewtonTriOmp::NPairHalfMultiNewtonTriOmp(LAMMPS *lmp) :
NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with Newton's 3rd law for triclinic
multi stencil is icollection-jcollection dependent
each owned atom i checks its own bin and other bins in triclinic stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfMultiNewtonTriOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
const double delta = 0.01 * force->angstrom;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,jbin,icollection,jcollection,which,ns,imol,iatom;
tagint itag,jtag,tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
int js;
int *collection = neighbor->collection;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itag = tag[i];
itype = type[i];
icollection = collection[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
ibin = atom2bin[i];
// loop through stencils for all collections
for (jcollection = 0; jcollection < ncollections; jcollection++) {
// if same collection use own bin
if (icollection == jcollection) jbin = ibin;
else jbin = coord2bin(x[i], jcollection);
// loop over all atoms in bins in stencil
// for triclinic:
// stencil is empty if i larger than j
// stencil is full if i smaller than j
// stencil is full if i same size as j
// for i smaller than j:
// must use itag/jtag to eliminate half the I/J interactions
// cannot use I/J exact coord comparision
// b/c transforming orthog -> lambda -> orthog for ghost atoms
// with an added PBC offset can shift all 3 coords by epsilon
s = stencil_multi[icollection][jcollection];
ns = nstencil_multi[icollection][jcollection];
for (k = 0; k < ns; k++) {
js = binhead_multi[jcollection][jbin + s[k]];
for (j = js; j >= 0; j = bins[j]) {
// if same size (same collection), exclude half of interactions
if (cutcollectionsq[icollection][icollection] ==
cutcollectionsq[jcollection][jcollection]) {
if (j <= i) continue;
if (j >= nlocal) {
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (fabs(x[j][2]-ztmp) > delta) {
if (x[j][2] < ztmp) continue;
} else if (fabs(x[j][1]-ytmp) > delta) {
if (x[j][1] < ytmp) continue;
} else {
if (x[j][0] < xtmp) continue;
}
}
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/multi/newton/tri/omp,
NPairHalfMultiNewtonTriOmp,
NP_HALF | NP_MULTI | NP_NEWTON | NP_TRI | NP_OMP);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_TRI_OMP_H
#define LMP_NPAIR_HALF_MULTI_NEWTON_TRI_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfMultiNewtonTriOmp : public NPair {
public:
NPairHalfMultiNewtonTriOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,146 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_multi_old_newtoff_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfMultiOldNewtoffOmp::NPairHalfMultiOldNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with partial Newton's 3rd law
each owned atom i checks own bin and other bins in stencil
multi-type stencil is itype dependent and is distance checked
pair stored once if i,j are both owned and i < j
pair stored by me if j is ghost (also stored by proc owning j)
------------------------------------------------------------------------- */
void NPairHalfMultiOldNewtoffOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
double *cutsq,*distsq;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms in other bins in stencil including self
// only store pair if i < j
// skip if i,j neighbor cutoff is less than bin distance
// stores own/own pairs only once
// stores own/ghost pairs on both procs
ibin = atom2bin[i];
s = stencil_multi_old[itype];
distsq = distsq_multi_old[itype];
cutsq = cutneighsq[itype];
ns = nstencil_multi_old[itype];
for (k = 0; k < ns; k++) {
for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) {
if (j <= i) continue;
jtype = type[j];
if (cutsq[jtype] < distsq[k]) continue;
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/multi/old/newtoff/omp,
NPairHalfMultiOldNewtoffOmp,
NP_HALF | NP_MULTI_OLD | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTOFF_OMP_H
#define LMP_NPAIR_HALF_MULTI_OLD_NEWTOFF_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfMultiOldNewtoffOmp : public NPair {
public:
NPairHalfMultiOldNewtoffOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,179 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_multi_old_newton_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfMultiOldNewtonOmp::NPairHalfMultiOldNewtonOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with full Newton's 3rd law
each owned atom i checks its own bin and other bins in Newton stencil
multi-type stencil is itype dependent and is distance checked
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfMultiOldNewtonOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
double *cutsq,*distsq;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over rest of atoms in i's bin, ghosts are at end of linked list
// if j is owned atom, store it, since j is beyond i in linked list
// if j is ghost, only store if j coords are "above and to the right" of i
for (j = bins[i]; j >= 0; j = bins[j]) {
if (j >= nlocal) {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp) {
if (x[j][1] < ytmp) continue;
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
// loop over all atoms in other bins in stencil, store every pair
// skip if i,j neighbor cutoff is less than bin distance
ibin = atom2bin[i];
s = stencil_multi_old[itype];
distsq = distsq_multi_old[itype];
cutsq = cutneighsq[itype];
ns = nstencil_multi_old[itype];
for (k = 0; k < ns; k++) {
for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) {
jtype = type[j];
if (cutsq[jtype] < distsq[k]) continue;
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/multi/old/newton/omp,
NPairHalfMultiOldNewtonOmp,
NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_OMP | NP_ORTHO);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTON_OMP_H
#define LMP_NPAIR_HALF_MULTI_OLD_NEWTON_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfMultiOldNewtonOmp : public NPair {
public:
NPairHalfMultiOldNewtonOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,165 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_multi_old_newton_tri_omp.h"
#include "npair_omp.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "molecule.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfMultiOldNewtonTriOmp::NPairHalfMultiOldNewtonTriOmp(LAMMPS *lmp) :
NPair(lmp) {}
/* ----------------------------------------------------------------------
binned neighbor list construction with Newton's 3rd law for triclinic
each owned atom i checks its own bin and other bins in triclinic stencil
multi-type stencil is itype dependent and is distance checked
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfMultiOldNewtonTriOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
const double delta = 0.01 * force->angstrom;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom;
tagint itag,jtag,tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*s;
double *cutsq,*distsq;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itag = tag[i];
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms in bins in stencil
// for triclinic, bin stencil is full in all 3 dims
// must use itag/jtag to eliminate half the I/J interactions
// cannot use I/J exact coord comparision
// b/c transforming orthog -> lambda -> orthog for ghost atoms
// with an added PBC offset can shift all 3 coords by epsilon
ibin = atom2bin[i];
s = stencil_multi_old[itype];
distsq = distsq_multi_old[itype];
cutsq = cutneighsq[itype];
ns = nstencil_multi_old[itype];
for (k = 0; k < ns; k++) {
for (j = binhead[ibin+s[k]]; j >= 0; j = bins[j]) {
jtype = type[j];
if (cutsq[jtype] < distsq[k]) continue;
if (j >= nlocal) {
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else {
if (fabs(x[j][2]-ztmp) > delta) {
if (x[j][2] < ztmp) continue;
} else if (fabs(x[j][1]-ytmp) > delta) {
if (x[j][1] < ytmp) continue;
} else {
if (x[j][0] < xtmp) continue;
}
}
}
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/multi/old/newton/tri/omp,
NPairHalfMultiOldNewtonTriOmp,
NP_HALF | NP_MULTI_OLD | NP_NEWTON | NP_TRI | NP_OMP);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_MULTI_OLD_NEWTON_TRI_OMP_H
#define LMP_NPAIR_HALF_MULTI_OLD_NEWTON_TRI_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfMultiOldNewtonTriOmp : public NPair {
public:
NPairHalfMultiOldNewtonTriOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,158 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_nsq_newtoff_ghost_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "group.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfNsqNewtoffGhostOmp::NPairHalfNsqNewtoffGhostOmp(LAMMPS *lmp) :
NPair(lmp) {}
/* ----------------------------------------------------------------------
N^2 / 2 search for neighbor pairs with partial Newton's 3rd law
include neighbors of ghost atoms, but no "special neighbors" for ghosts
pair stored once if i,j are both owned and i < j
pair stored by me if i owned and j ghost (also stored by proc owning j)
pair stored once if i,j are both ghost and i < j
------------------------------------------------------------------------- */
void NPairHalfNsqNewtoffGhostOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
const int nall = nlocal + atom->nghost;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nall);
int i,j,n,itype,jtype,which,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned & ghost atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over remaining atoms, owned and ghost
// only store pair if i < j
// stores own/own pairs only once
// stores own/ghost pairs with owned atom only, on both procs
// stores ghost/ghost pairs only once
// no molecular test when i = ghost atom
if (i < nlocal) {
for (j = i+1; j < nall; j++) {
if (includegroup && !(mask[j] & bitmask)) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
} else {
for (j = i+1; j < nall; j++) {
if (includegroup && !(mask[j] & bitmask)) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) neighptr[n++] = j;
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = atom->nlocal;
list->gnum = nall - atom->nlocal;
}

View File

@ -1,134 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_nsq_newtoff_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "group.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfNsqNewtoffOmp::NPairHalfNsqNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
N^2 / 2 search for neighbor pairs with partial Newton's 3rd law
pair stored once if i,j are both owned and i < j
pair stored by me if j is ghost (also stored by proc owning j)
------------------------------------------------------------------------- */
void NPairHalfNsqNewtoffOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
const int nall = atom->nlocal + atom->nghost;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,n,itype,jtype,which,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
// loop over owned atoms, storing neighbors
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over remaining atoms, owned and ghost
// only store pair if i < j
for (j = i+1; j < nall; j++) {
if (includegroup && !(mask[j] & bitmask)) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/nsq/newtoff/omp,
NPairHalfNsqNewtoffOmp,
NP_HALF | NP_NSQ | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_OMP_H
#define LMP_NPAIR_HALF_NSQ_NEWTOFF_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfNsqNewtoffOmp : public NPair {
public:
NPairHalfNsqNewtoffOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,167 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_nsq_newton_omp.h"
#include "npair_omp.h"
#include "atom.h"
#include "atom_vec.h"
#include "domain.h"
#include "error.h"
#include "force.h"
#include "group.h"
#include "molecule.h"
#include "my_page.h"
#include "neigh_list.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfNsqNewtonOmp::NPairHalfNsqNewtonOmp(LAMMPS *lmp) : NPair(lmp) {}
/* ----------------------------------------------------------------------
N^2 / 2 search for neighbor pairs with full Newton's 3rd law
every pair stored exactly once by some processor
decision on ghost atoms based on itag,jtag tests
------------------------------------------------------------------------- */
void NPairHalfNsqNewtonOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
const double delta = 0.01 * force->angstrom;
const int triclinic = domain->triclinic;
NPAIR_OMP_INIT;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,n,itype,jtype,which,imol,iatom;
tagint itag,jtag,tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr;
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int nall = atom->nlocal + atom->nghost;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
ipage.reset();
for (i = ifrom; i < ito; i++) {
n = 0;
neighptr = ipage.vget();
itag = tag[i];
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over remaining atoms, owned and ghost
// use itag/jtap comparision to eliminate half the interactions
// itag = jtag is possible for long cutoffs that include images of self
// for triclinic, must use delta to eliminate half the I/J interactions
// cannot use I/J exact coord comparision as for orthog
// b/c transforming orthog -> lambda -> orthog for ghost atoms
// with an added PBC offset can shift all 3 coords by epsilon
for (j = i+1; j < nall; j++) {
if (includegroup && !(mask[j] & bitmask)) continue;
if (j >= nlocal) {
jtag = tag[j];
if (itag > jtag) {
if ((itag+jtag) % 2 == 0) continue;
} else if (itag < jtag) {
if ((itag+jtag) % 2 == 1) continue;
} else if (triclinic) {
if (fabs(x[j][2]-ztmp) > delta) {
if (x[j][2] < ztmp) continue;
} else if (fabs(x[j][1]-ytmp) > delta) {
if (x[j][1] < ytmp) continue;
} else {
if (x[j][0] < xtmp) continue;
}
} else {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp) {
if (x[j][1] < ytmp) continue;
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if (domain->minimum_image_check(delx,dely,delz))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/nsq/newton/omp,
NPairHalfNsqNewtonOmp,
NP_HALF | NP_NSQ | NP_NEWTON | NP_OMP | NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_NSQ_NEWTON_OMP_H
#define LMP_NPAIR_HALF_NSQ_NEWTON_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfNsqNewtonOmp : public NPair {
public:
NPairHalfNsqNewtonOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,203 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_respa_bin_newtoff_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfRespaBinNewtoffOmp::NPairHalfRespaBinNewtoffOmp(LAMMPS *lmp) :
NPair(lmp) {}
/* ----------------------------------------------------------------------
multiple respa lists
binned neighbor list construction with partial Newton's 3rd law
each owned atom i checks own bin and surrounding bins in non-Newton stencil
pair stored once if i,j are both owned and i < j
pair stored by me if j is ghost (also stored by proc owning j)
------------------------------------------------------------------------- */
void NPairHalfRespaBinNewtoffOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
const int respamiddle = list->respamiddle;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*neighptr_inner,*neighptr_middle;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
int *ilist_inner = list->ilist_inner;
int *numneigh_inner = list->numneigh_inner;
int **firstneigh_inner = list->firstneigh_inner;
int *ilist_middle,*numneigh_middle,**firstneigh_middle;
if (respamiddle) {
ilist_middle = list->ilist_middle;
numneigh_middle = list->numneigh_middle;
firstneigh_middle = list->firstneigh_middle;
}
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
MyPage<int> &ipage_inner = list->ipage_inner[tid];
ipage.reset();
ipage_inner.reset();
MyPage<int> *ipage_middle;
if (respamiddle) {
ipage_middle = list->ipage_middle + tid;
ipage_middle->reset();
}
int which = 0;
int minchange = 0;
for (i = ifrom; i < ito; i++) {
n = n_inner = 0;
neighptr = ipage.vget();
neighptr_inner = ipage_inner.vget();
if (respamiddle) {
n_middle = 0;
neighptr_middle = ipage_middle->vget();
}
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
ibin = atom2bin[i];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over all atoms in surrounding bins in stencil including self
// only store pair if i < j
// stores own/own pairs only once
// stores own/ghost pairs on both procs
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
if (j <= i) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if ((minchange = domain->minimum_image_check(delx,dely,delz)))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
if (rsq < cut_inner_sq) {
if (which == 0) neighptr_inner[n_inner++] = j;
else if (minchange) neighptr_inner[n_inner++] = j;
else if (which > 0)
neighptr_inner[n_inner++] = j ^ (which << SBBITS);
}
if (respamiddle &&
rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
if (which == 0) neighptr_middle[n_middle++] = j;
else if (minchange) neighptr_middle[n_middle++] = j;
else if (which > 0)
neighptr_middle[n_middle++] = j ^ (which << SBBITS);
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
ilist_inner[i] = i;
firstneigh_inner[i] = neighptr_inner;
numneigh_inner[i] = n_inner;
ipage.vgot(n_inner);
if (ipage_inner.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
if (respamiddle) {
ilist_middle[i] = i;
firstneigh_middle[i] = neighptr_middle;
numneigh_middle[i] = n_middle;
ipage_middle->vgot(n_middle);
if (ipage_middle->status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->inum_inner = nlocal;
if (respamiddle) list->inum_middle = nlocal;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/respa/bin/newtoff/omp,
NPairHalfRespaBinNewtoffOmp,
NP_HALF | NP_RESPA | NP_BIN | NP_NEWTOFF | NP_OMP |
NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_OMP_H
#define LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfRespaBinNewtoffOmp : public NPair {
public:
NPairHalfRespaBinNewtoffOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,249 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_respa_bin_newton_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfRespaBinNewtonOmp::NPairHalfRespaBinNewtonOmp(LAMMPS *lmp) :
NPair(lmp) {}
/* ----------------------------------------------------------------------
multiple respa lists
binned neighbor list construction with full Newton's 3rd law
each owned atom i checks its own bin and other bins in Newton stencil
every pair stored exactly once by some processor
------------------------------------------------------------------------- */
void NPairHalfRespaBinNewtonOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
const int respamiddle = list->respamiddle;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*neighptr_inner,*neighptr_middle;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
int *ilist_inner = list->ilist_inner;
int *numneigh_inner = list->numneigh_inner;
int **firstneigh_inner = list->firstneigh_inner;
int *ilist_middle,*numneigh_middle,**firstneigh_middle;
if (respamiddle) {
ilist_middle = list->ilist_middle;
numneigh_middle = list->numneigh_middle;
firstneigh_middle = list->firstneigh_middle;
}
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
MyPage<int> &ipage_inner = list->ipage_inner[tid];
ipage.reset();
ipage_inner.reset();
MyPage<int> *ipage_middle;
if (respamiddle) {
ipage_middle = list->ipage_middle + tid;
ipage_middle->reset();
}
int which = 0;
int minchange = 0;
for (i = ifrom; i < ito; i++) {
n = n_inner = 0;
neighptr = ipage.vget();
neighptr_inner = ipage_inner.vget();
if (respamiddle) {
n_middle = 0;
neighptr_middle = ipage_middle->vget();
}
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over rest of atoms in i's bin, ghosts are at end of linked list
// if j is owned atom, store it, since j is beyond i in linked list
// if j is ghost, only store if j coords are "above and to the right" of i
for (j = bins[i]; j >= 0; j = bins[j]) {
if (j >= nlocal) {
if (x[j][2] < ztmp) continue;
if (x[j][2] == ztmp) {
if (x[j][1] < ytmp) continue;
if (x[j][1] == ytmp && x[j][0] < xtmp) continue;
}
}
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if ((minchange = domain->minimum_image_check(delx,dely,delz)))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
if (rsq < cut_inner_sq) {
if (which == 0) neighptr_inner[n_inner++] = j;
else if (minchange) neighptr_inner[n_inner++] = j;
else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS);
}
if (respamiddle &&
rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
if (which == 0) neighptr_middle[n_middle++] = j;
else if (minchange) neighptr_middle[n_middle++] = j;
else if (which > 0)
neighptr_middle[n_middle++] = j ^ (which << SBBITS);
}
}
}
// loop over all atoms in other bins in stencil, store every pair
ibin = atom2bin[i];
for (k = 0; k < nstencil; k++) {
for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) {
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if ((minchange = domain->minimum_image_check(delx,dely,delz)))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
if (rsq < cut_inner_sq) {
if (which == 0) neighptr_inner[n_inner++] = j;
else if (minchange) neighptr_inner[n_inner++] = j;
else if (which > 0)
neighptr_inner[n_inner++] = j ^ (which << SBBITS);
}
if (respamiddle &&
rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
if (which == 0) neighptr_middle[n_middle++] = j;
else if (minchange) neighptr_middle[n_middle++] = j;
else if (which > 0)
neighptr_middle[n_middle++] = j ^ (which << SBBITS);
}
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
ilist_inner[i] = i;
firstneigh_inner[i] = neighptr_inner;
numneigh_inner[i] = n_inner;
ipage.vgot(n_inner);
if (ipage_inner.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
if (respamiddle) {
ilist_middle[i] = i;
firstneigh_middle[i] = neighptr_middle;
numneigh_middle[i] = n_middle;
ipage_middle->vgot(n_middle);
if (ipage_middle->status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->inum_inner = nlocal;
if (respamiddle) list->inum_middle = nlocal;
}

View File

@ -1,38 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/respa/bin/newton/tri/omp,
NPairHalfRespaBinNewtonTriOmp,
NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_OMP_H
#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfRespaBinNewtonTriOmp : public NPair {
public:
NPairHalfRespaBinNewtonTriOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

View File

@ -1,197 +0,0 @@
// 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 "omp_compat.h"
#include "npair_half_respa_nsq_newtoff_omp.h"
#include "npair_omp.h"
#include "neigh_list.h"
#include "atom.h"
#include "atom_vec.h"
#include "group.h"
#include "molecule.h"
#include "domain.h"
#include "my_page.h"
#include "error.h"
using namespace LAMMPS_NS;
/* ---------------------------------------------------------------------- */
NPairHalfRespaNsqNewtoffOmp::NPairHalfRespaNsqNewtoffOmp(LAMMPS *lmp) :
NPair(lmp) {}
/* ----------------------------------------------------------------------
multiple respa lists
N^2 / 2 search for neighbor pairs with partial Newton's 3rd law
pair added to list if atoms i and j are both owned and i < j
pair added if j is ghost (also stored by proc owning j)
------------------------------------------------------------------------- */
void NPairHalfRespaNsqNewtoffOmp::build(NeighList *list)
{
const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal;
const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;
const int molecular = atom->molecular;
const int moltemplate = (molecular == Atom::TEMPLATE) ? 1 : 0;
NPAIR_OMP_INIT;
const int respamiddle = list->respamiddle;
#if defined(_OPENMP)
#pragma omp parallel LMP_DEFAULT_NONE LMP_SHARED(list)
#endif
NPAIR_OMP_SETUP(nlocal);
int i,j,n,itype,jtype,n_inner,n_middle,imol,iatom;
tagint tagprev;
double xtmp,ytmp,ztmp,delx,dely,delz,rsq;
int *neighptr,*neighptr_inner,*neighptr_middle;
// loop over each atom, storing neighbors
double **x = atom->x;
int *type = atom->type;
int *mask = atom->mask;
tagint *tag = atom->tag;
tagint *molecule = atom->molecule;
tagint **special = atom->special;
int **nspecial = atom->nspecial;
int *molindex = atom->molindex;
int *molatom = atom->molatom;
Molecule **onemols = atom->avec->onemols;
int nall = atom->nlocal + atom->nghost;
int *ilist = list->ilist;
int *numneigh = list->numneigh;
int **firstneigh = list->firstneigh;
int *ilist_inner = list->ilist_inner;
int *numneigh_inner = list->numneigh_inner;
int **firstneigh_inner = list->firstneigh_inner;
int *ilist_middle,*numneigh_middle,**firstneigh_middle;
if (respamiddle) {
ilist_middle = list->ilist_middle;
numneigh_middle = list->numneigh_middle;
firstneigh_middle = list->firstneigh_middle;
}
// each thread has its own page allocator
MyPage<int> &ipage = list->ipage[tid];
MyPage<int> &ipage_inner = list->ipage_inner[tid];
ipage.reset();
ipage_inner.reset();
MyPage<int> *ipage_middle;
if (respamiddle) {
ipage_middle = list->ipage_middle + tid;
ipage_middle->reset();
}
int which = 0;
int minchange = 0;
for (i = ifrom; i < ito; i++) {
n = n_inner = 0;
neighptr = ipage.vget();
neighptr_inner = ipage_inner.vget();
if (respamiddle) {
n_middle = 0;
neighptr_middle = ipage_middle->vget();
}
itype = type[i];
xtmp = x[i][0];
ytmp = x[i][1];
ztmp = x[i][2];
if (moltemplate) {
imol = molindex[i];
iatom = molatom[i];
tagprev = tag[i] - iatom - 1;
}
// loop over remaining atoms, owned and ghost
for (j = i+1; j < nall; j++) {
if (includegroup && !(mask[j] & bitmask)) continue;
jtype = type[j];
if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue;
delx = xtmp - x[j][0];
dely = ytmp - x[j][1];
delz = ztmp - x[j][2];
rsq = delx*delx + dely*dely + delz*delz;
if (rsq <= cutneighsq[itype][jtype]) {
if (molecular != Atom::ATOMIC) {
if (!moltemplate)
which = find_special(special[i],nspecial[i],tag[j]);
else if (imol >= 0)
which = find_special(onemols[imol]->special[iatom],
onemols[imol]->nspecial[iatom],
tag[j]-tagprev);
else which = 0;
if (which == 0) neighptr[n++] = j;
else if ((minchange = domain->minimum_image_check(delx,dely,delz)))
neighptr[n++] = j;
else if (which > 0) neighptr[n++] = j ^ (which << SBBITS);
} else neighptr[n++] = j;
if (rsq < cut_inner_sq) {
if (which == 0) neighptr_inner[n_inner++] = j;
else if (minchange) neighptr_inner[n_inner++] = j;
else if (which > 0) neighptr_inner[n_inner++] = j ^ (which << SBBITS);
}
if (respamiddle && rsq < cut_middle_sq && rsq > cut_middle_inside_sq) {
if (which == 0) neighptr_middle[n_middle++] = j;
else if (minchange) neighptr_middle[n_middle++] = j;
else if (which > 0)
neighptr_middle[n_middle++] = j ^ (which << SBBITS);
}
}
}
ilist[i] = i;
firstneigh[i] = neighptr;
numneigh[i] = n;
ipage.vgot(n);
if (ipage.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
ilist_inner[i] = i;
firstneigh_inner[i] = neighptr_inner;
numneigh_inner[i] = n_inner;
ipage.vgot(n_inner);
if (ipage_inner.status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
if (respamiddle) {
ilist_middle[i] = i;
firstneigh_middle[i] = neighptr_middle;
numneigh_middle[i] = n_middle;
ipage_middle->vgot(n_middle);
if (ipage_middle->status())
error->one(FLERR,"Neighbor list overflow, boost neigh_modify one");
}
}
NPAIR_OMP_CLOSE;
list->inum = nlocal;
list->inum_inner = nlocal;
if (respamiddle) list->inum_middle = nlocal;
}

View File

@ -1,39 +0,0 @@
/* -*- 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.
------------------------------------------------------------------------- */
#ifdef NPAIR_CLASS
// clang-format off
NPairStyle(half/respa/nsq/newtoff/omp,
NPairHalfRespaNsqNewtoffOmp,
NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTOFF | NP_OMP |
NP_ORTHO | NP_TRI);
// clang-format on
#else
#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_OMP_H
#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_OMP_H
#include "npair.h"
namespace LAMMPS_NS {
class NPairHalfRespaNsqNewtoffOmp : public NPair {
public:
NPairHalfRespaNsqNewtoffOmp(class LAMMPS *);
void build(class NeighList *) override;
};
} // namespace LAMMPS_NS
#endif
#endif

Some files were not shown because too many files have changed in this diff Show More