Merge branch 'develop' of github.com:lammps/lammps into kk_half_thread
This commit is contained in:
@ -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>`
|
||||
|
||||
@ -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
|
||||
|
||||
97
doc/src/compute_reaxff_atom.rst
Normal file
97
doc/src/compute_reaxff_atom.rst
Normal 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*.
|
||||
@ -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
|
||||
""""""""""""""""
|
||||
|
||||
@ -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
|
||||
"""""""
|
||||
|
||||
@ -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
2
src/.gitignore
vendored
@ -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
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -39,6 +39,7 @@ using namespace MathConst;
|
||||
|
||||
AngleFourier::AngleFourier(LAMMPS *lmp) : Angle(lmp)
|
||||
{
|
||||
born_matrix_enable = 1;
|
||||
k = nullptr;
|
||||
C0 = nullptr;
|
||||
C1 = nullptr;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) ;
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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"
|
||||
@ -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"
|
||||
|
||||
298
src/INTEL/npair_bin_intel.cpp
Normal file
298
src/INTEL/npair_bin_intel.cpp
Normal 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
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
}
|
||||
@ -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");
|
||||
128
src/INTEL/npair_halffull_intel.h
Normal file
128
src/INTEL/npair_halffull_intel.h
Normal 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
|
||||
@ -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
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -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
|
||||
70
src/INTEL/nstencil_bin_intel.cpp
Normal file
70
src/INTEL/nstencil_bin_intel.cpp
Normal 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>;
|
||||
}
|
||||
65
src/INTEL/nstencil_bin_intel.h
Normal file
65
src/INTEL/nstencil_bin_intel.h
Normal 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
|
||||
@ -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>;
|
||||
}
|
||||
@ -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;
|
||||
};
|
||||
|
||||
@ -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
|
||||
|
||||
195
src/KOKKOS/compute_reaxff_atom_kokkos.cpp
Normal file
195
src/KOKKOS/compute_reaxff_atom_kokkos.cpp
Normal 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
|
||||
}
|
||||
66
src/KOKKOS/compute_reaxff_atom_kokkos.h
Normal file
66
src/KOKKOS/compute_reaxff_atom_kokkos.h
Normal 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
|
||||
@ -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>
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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>;
|
||||
}
|
||||
@ -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;
|
||||
};
|
||||
|
||||
277
src/OPENMP/npair_bin_omp.cpp
Normal file
277
src/OPENMP/npair_bin_omp.cpp
Normal 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
119
src/OPENMP/npair_bin_omp.h
Normal 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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
|
||||
@ -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;
|
||||
}
|
||||
@ -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
Reference in New Issue
Block a user