diff --git a/src/.gitignore b/src/.gitignore index a7c647e273..6b90b64752 100644 --- a/src/.gitignore +++ b/src/.gitignore @@ -18,6 +18,8 @@ /*_tally.cpp /*_rx.h /*_rx.cpp +/*_ssa.h +/*_ssa.cpp /kokkos.cpp /kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 93adf58ef5..4f1d83f29d 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -105,11 +105,16 @@ action modify_kokkos.cpp action modify_kokkos.h action neigh_bond_kokkos.cpp action neigh_bond_kokkos.h -action neigh_full_kokkos.h action neigh_list_kokkos.cpp action neigh_list_kokkos.h action neighbor_kokkos.cpp action neighbor_kokkos.h +action npair_copy_kokkos.cpp +action npair_copy_kokkos.h +action npair_kokkos.cpp +action npair_kokkos.h +action nbin_kokkos.cpp +action nbin_kokkos.h action math_special_kokkos.cpp action math_special_kokkos.h action pair_buck_coul_cut_kokkos.cpp diff --git a/src/KOKKOS/fix_qeq_reax_kokkos.cpp b/src/KOKKOS/fix_qeq_reax_kokkos.cpp index 0c0039a18a..844d48dae0 100644 --- a/src/KOKKOS/fix_qeq_reax_kokkos.cpp +++ b/src/KOKKOS/fix_qeq_reax_kokkos.cpp @@ -125,12 +125,10 @@ void FixQEqReaxKokkos::init() neighbor->requests[irequest]->pair = 0; neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else { //if (neighflag == HALF || neighflag == HALFTHREAD) neighbor->requests[irequest]->fix = 1; neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } } diff --git a/src/KOKKOS/kokkos.cpp b/src/KOKKOS/kokkos.cpp index 72bf094e4b..763c97d69b 100644 --- a/src/KOKKOS/kokkos.cpp +++ b/src/KOKKOS/kokkos.cpp @@ -168,7 +168,6 @@ void KokkosLMP::accelerator(int narg, char **arg) else neighflag = HALF; } else if (strcmp(arg[iarg+1],"n2") == 0) neighflag = N2; - else if (strcmp(arg[iarg+1],"full/cluster") == 0) neighflag = FULLCLUSTER; else error->all(FLERR,"Illegal package kokkos command"); iarg += 2; } else if (strcmp(arg[iarg],"binsize") == 0) { @@ -232,20 +231,6 @@ void KokkosLMP::accelerator(int narg, char **arg) called by Finish ------------------------------------------------------------------------- */ -int KokkosLMP::neigh_list_kokkos(int m) -{ - NeighborKokkos *nk = (NeighborKokkos *) neighbor; - if (nk->lists_host[m] && nk->lists_host[m]->d_numneigh.dimension_0()) - return 1; - if (nk->lists_device[m] && nk->lists_device[m]->d_numneigh.dimension_0()) - return 1; - return 0; -} - -/* ---------------------------------------------------------------------- - called by Finish -------------------------------------------------------------------------- */ - int KokkosLMP::neigh_count(int m) { int inum; @@ -255,28 +240,30 @@ int KokkosLMP::neigh_count(int m) ArrayTypes::t_int_1d h_numneigh; NeighborKokkos *nk = (NeighborKokkos *) neighbor; - if (nk->lists_host[m]) { - inum = nk->lists_host[m]->inum; + if (nk->lists[m]->execution_space == Host) { + NeighListKokkos* nlistKK = (NeighListKokkos*) nk->lists[m]; + inum = nlistKK->inum; #ifndef KOKKOS_USE_CUDA_UVM - h_ilist = Kokkos::create_mirror_view(nk->lists_host[m]->d_ilist); - h_numneigh = Kokkos::create_mirror_view(nk->lists_host[m]->d_numneigh); + h_ilist = Kokkos::create_mirror_view(nlistKK->d_ilist); + h_numneigh = Kokkos::create_mirror_view(nlistKK->d_numneigh); #else - h_ilist = nk->lists_host[m]->d_ilist; - h_numneigh = nk->lists_host[m]->d_numneigh; + h_ilist = nlistKK->d_ilist; + h_numneigh = nlistKK->d_numneigh; #endif - Kokkos::deep_copy(h_ilist,nk->lists_host[m]->d_ilist); - Kokkos::deep_copy(h_numneigh,nk->lists_host[m]->d_numneigh); - } else if (nk->lists_device[m]) { - inum = nk->lists_device[m]->inum; + Kokkos::deep_copy(h_ilist,nlistKK->d_ilist); + Kokkos::deep_copy(h_numneigh,nlistKK->d_numneigh); + } else if (nk->lists[m]->execution_space == Device) { + NeighListKokkos* nlistKK = (NeighListKokkos*) nk->lists[m]; + inum = nlistKK->inum; #ifndef KOKKOS_USE_CUDA_UVM - h_ilist = Kokkos::create_mirror_view(nk->lists_device[m]->d_ilist); - h_numneigh = Kokkos::create_mirror_view(nk->lists_device[m]->d_numneigh); + h_ilist = Kokkos::create_mirror_view(nlistKK->d_ilist); + h_numneigh = Kokkos::create_mirror_view(nlistKK->d_numneigh); #else - h_ilist = nk->lists_device[m]->d_ilist; - h_numneigh = nk->lists_device[m]->d_numneigh; + h_ilist = nlistKK->d_ilist; + h_numneigh = nlistKK->d_numneigh; #endif - Kokkos::deep_copy(h_ilist,nk->lists_device[m]->d_ilist); - Kokkos::deep_copy(h_numneigh,nk->lists_device[m]->d_numneigh); + Kokkos::deep_copy(h_ilist,nlistKK->d_ilist); + Kokkos::deep_copy(h_numneigh,nlistKK->d_numneigh); } for (int i = 0; i < inum; i++) nneigh += h_numneigh[h_ilist[i]]; diff --git a/src/KOKKOS/kokkos.h b/src/KOKKOS/kokkos.h index 1058affcfc..3b91a56ea7 100644 --- a/src/KOKKOS/kokkos.h +++ b/src/KOKKOS/kokkos.h @@ -34,7 +34,6 @@ class KokkosLMP : protected Pointers { KokkosLMP(class LAMMPS *, int, char **); ~KokkosLMP(); void accelerator(int, char **); - int neigh_list_kokkos(int); int neigh_count(int); private: static void my_signal_handler(int); diff --git a/src/KOKKOS/nbin_kokkos.cpp b/src/KOKKOS/nbin_kokkos.cpp new file mode 100644 index 0000000000..9a73e23b42 --- /dev/null +++ b/src/KOKKOS/nbin_kokkos.cpp @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nbin_kokkos.h" +#include "neighbor.h" +#include "atom_kokkos.h" +#include "group.h" +#include "domain.h" +#include "comm.h" +#include "update.h" +#include "error.h" +#include "atom_masks.h" + +using namespace LAMMPS_NS; + +enum{NSQ,BIN,MULTI}; // also in Neighbor + +#define SMALL 1.0e-6 +#define CUT2BIN_RATIO 100 + +/* ---------------------------------------------------------------------- */ + +template +NBinKokkos::NBinKokkos(LAMMPS *lmp) : NBinStandard(lmp) { + atoms_per_bin = 16; + + d_resize = typename AT::t_int_scalar("NeighborKokkosFunctor::resize"); +#ifndef KOKKOS_USE_CUDA_UVM + h_resize = Kokkos::create_mirror_view(d_resize); +#else + h_resize = d_resize; +#endif + h_resize() = 1; + +} + +/* ---------------------------------------------------------------------- + setup neighbor binning geometry + bin numbering in each dimension is global: + 0 = 0.0 to binsize, 1 = binsize to 2*binsize, etc + nbin-1,nbin,etc = bbox-binsize to bbox, bbox to bbox+binsize, etc + -1,-2,etc = -binsize to 0.0, -2*binsize to -binsize, etc + code will work for any binsize + since next(xyz) and stencil extend as far as necessary + binsize = 1/2 of cutoff is roughly optimal + for orthogonal boxes: + a dim must be filled exactly by integer # of bins + in periodic, procs on both sides of PBC must see same bin boundary + in non-periodic, coord2bin() still assumes this by use of nbin xyz + for triclinic boxes: + tilted simulation box cannot contain integer # of bins + stencil & neigh list built differently to account for this + mbinlo = lowest global bin any of my ghost atoms could fall into + mbinhi = highest global bin any of my ghost atoms could fall into + mbin = number of bins I need in a dimension +------------------------------------------------------------------------- */ + +template +void NBinKokkos::bin_atoms_setup(int nall) +{ + if (mbins > k_bins.d_view.dimension_0()) { + k_bins = DAT::tdual_int_2d("Neighbor::d_bins",mbins,atoms_per_bin); + bins = k_bins.view(); + + k_bincount = DAT::tdual_int_1d("Neighbor::d_bincount",mbins); + bincount = k_bincount.view(); + last_bin_memory = update->ntimestep; + } + + last_bin = update->ntimestep; +} + +/* ---------------------------------------------------------------------- + bin owned and ghost atoms +------------------------------------------------------------------------- */ + +template +void NBinKokkos::bin_atoms() +{ + h_resize() = 1; + + while(h_resize() > 0) { + h_resize() = 0; + deep_copy(d_resize, h_resize); + + MemsetZeroFunctor f_zero; + f_zero.ptr = (void*) k_bincount.view().ptr_on_device(); + Kokkos::parallel_for(mbins, f_zero); + DeviceType::fence(); + + atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); + x = atomKK->k_x.view(); + + bboxlo_[0] = bboxlo[0]; bboxlo_[1] = bboxlo[1]; bboxlo_[2] = bboxlo[2]; + bboxhi_[0] = bboxhi[0]; bboxhi_[1] = bboxhi[1]; bboxhi_[2] = bboxhi[2]; + + NPairKokkosBinAtomsFunctor f(*this); + + Kokkos::parallel_for(atom->nlocal+atom->nghost, f); + DeviceType::fence(); + + deep_copy(h_resize, d_resize); + if(h_resize()) { + + atoms_per_bin += 16; + k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin); + bins = k_bins.view(); + c_bins = bins; + last_bin_memory = update->ntimestep; + } + } +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +void NBinKokkos::binatomsItem(const int &i) const +{ + const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2)); + + const int ac = Kokkos::atomic_fetch_add(&bincount[ibin], (int)1); + if(ac < bins.dimension_1()) { + bins(ibin, ac) = i; + } else { + d_resize() = 1; + } +} + +namespace LAMMPS_NS { +template class NBinKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class NBinKokkos; +#endif +} diff --git a/src/KOKKOS/nbin_kokkos.h b/src/KOKKOS/nbin_kokkos.h new file mode 100644 index 0000000000..de3cf41d19 --- /dev/null +++ b/src/KOKKOS/nbin_kokkos.h @@ -0,0 +1,153 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NBIN_CLASS + +NBinStyle(kk/host, + NBinKokkos, + NB_KOKKOS_HOST) + +NBinStyle(kk/device, + NBinKokkos, + NB_KOKKOS_DEVICE) + +#else + +#ifndef LMP_NBIN_KOKKOS_H +#define LMP_NBIN_KOKKOS_H + +#include "nbin_standard.h" +#include "kokkos_type.h" + +namespace LAMMPS_NS { + +template +class NBinKokkos : public NBinStandard { + public: + typedef ArrayTypes AT; + + NBinKokkos(class LAMMPS *); + ~NBinKokkos() {} + void bin_atoms_setup(int); + void bin_atoms(); + + int atoms_per_bin; + DAT::tdual_int_1d k_bincount; + DAT::tdual_int_2d k_bins; + + typename AT::t_int_1d bincount; + const typename AT::t_int_1d_const c_bincount; + typename AT::t_int_2d bins; + typename AT::t_int_2d_const c_bins; + typename AT::t_int_scalar d_resize; + typename ArrayTypes::t_int_scalar h_resize; + typename AT::t_x_array_randomread x; + + KOKKOS_INLINE_FUNCTION + void binatomsItem(const int &i) const; + + KOKKOS_INLINE_FUNCTION + int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z) const + { + int ix,iy,iz; + + if (x >= bboxhi_[0]) + ix = static_cast ((x-bboxhi_[0])*bininvx) + nbinx; + else if (x >= bboxlo_[0]) { + ix = static_cast ((x-bboxlo_[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo_[0])*bininvx) - 1; + + if (y >= bboxhi_[1]) + iy = static_cast ((y-bboxhi_[1])*bininvy) + nbiny; + else if (y >= bboxlo_[1]) { + iy = static_cast ((y-bboxlo_[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo_[1])*bininvy) - 1; + + if (z >= bboxhi_[2]) + iz = static_cast ((z-bboxhi_[2])*bininvz) + nbinz; + else if (z >= bboxlo_[2]) { + iz = static_cast ((z-bboxlo_[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo_[2])*bininvz) - 1; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + KOKKOS_INLINE_FUNCTION + int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z, int* i) const + { + int ix,iy,iz; + + if (x >= bboxhi_[0]) + ix = static_cast ((x-bboxhi_[0])*bininvx) + nbinx; + else if (x >= bboxlo_[0]) { + ix = static_cast ((x-bboxlo_[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo_[0])*bininvx) - 1; + + if (y >= bboxhi_[1]) + iy = static_cast ((y-bboxhi_[1])*bininvy) + nbiny; + else if (y >= bboxlo_[1]) { + iy = static_cast ((y-bboxlo_[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo_[1])*bininvy) - 1; + + if (z >= bboxhi_[2]) + iz = static_cast ((z-bboxhi_[2])*bininvz) + nbinz; + else if (z >= bboxlo_[2]) { + iz = static_cast ((z-bboxlo_[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo_[2])*bininvz) - 1; + + i[0] = ix - mbinxlo; + i[1] = iy - mbinylo; + i[2] = iz - mbinzlo; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + private: + double bboxlo_[3],bboxhi_[3]; +}; + +template +struct NPairKokkosBinAtomsFunctor { + typedef DeviceType device_type; + + const NBinKokkos c; + + NPairKokkosBinAtomsFunctor(const NBinKokkos &_c): + c(_c) {}; + ~NPairKokkosBinAtomsFunctor() {} + KOKKOS_INLINE_FUNCTION + void operator() (const int & i) const { + c.binatomsItem(i); + } +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/neigh_list_kokkos.cpp b/src/KOKKOS/neigh_list_kokkos.cpp index cbba2120bd..b1b4e4467a 100644 --- a/src/KOKKOS/neigh_list_kokkos.cpp +++ b/src/KOKKOS/neigh_list_kokkos.cpp @@ -34,9 +34,8 @@ void NeighListKokkos::clean_copy() ipage = NULL; dpage = NULL; - maxstencil = 0; - ghostflag = 0; - maxstencil_multi = 0; + + maxatoms = 0; } /* ---------------------------------------------------------------------- */ @@ -70,49 +69,6 @@ void NeighListKokkos::grow(int nmax) /* ---------------------------------------------------------------------- */ -template -void NeighListKokkos::stencil_allocate(int smax, int style) -{ - int i; - - if (style == BIN) { - if (smax > maxstencil) { - maxstencil = smax; - d_stencil = - memory->create_kokkos(d_stencil,h_stencil,stencil,maxstencil, - "neighlist:stencil"); - if (ghostflag) { - memory->create_kokkos(d_stencilxyz,h_stencilxyz,stencilxyz,maxstencil, - 3,"neighlist:stencilxyz"); - } - } - - } else { - int n = atom->ntypes; - if (maxstencil_multi == 0) { - nstencil_multi = new int[n+1]; - stencil_multi = new int*[n+1]; - distsq_multi = new double*[n+1]; - for (i = 1; i <= n; i++) { - nstencil_multi[i] = 0; - stencil_multi[i] = NULL; - distsq_multi[i] = NULL; - } - } - if (smax > maxstencil_multi) { - maxstencil_multi = smax; - for (i = 1; i <= n; i++) { - memory->destroy(stencil_multi[i]); - memory->destroy(distsq_multi[i]); - memory->create(stencil_multi[i],maxstencil_multi, - "neighlist:stencil_multi"); - memory->create(distsq_multi[i],maxstencil_multi, - "neighlist:distsq_multi"); - } - } - } -} - namespace LAMMPS_NS { template class NeighListKokkos; #ifdef KOKKOS_HAVE_CUDA diff --git a/src/KOKKOS/neigh_list_kokkos.h b/src/KOKKOS/neigh_list_kokkos.h index 85f0f38d2c..45e768927c 100644 --- a/src/KOKKOS/neigh_list_kokkos.h +++ b/src/KOKKOS/neigh_list_kokkos.h @@ -20,7 +20,7 @@ namespace LAMMPS_NS { -enum{FULL=1u,HALFTHREAD=2u,HALF=4u,N2=8u,FULLCLUSTER=16u}; +enum{FULL=1u,HALFTHREAD=2u,HALF=4u,N2=8u}; class AtomNeighbors { @@ -74,14 +74,12 @@ public: typename DAT::tdual_int_1d k_ilist; // local indices of I atoms typename ArrayTypes::t_int_1d d_ilist; typename ArrayTypes::t_int_1d d_numneigh; // # of J neighs for each I - typename ArrayTypes::t_int_1d d_stencil; // # of J neighs for each I - typename ArrayTypes::t_int_1d h_stencil; // # of J neighs per I - typename ArrayTypes::t_int_1d_3 d_stencilxyz; - typename ArrayTypes::t_int_1d_3 h_stencilxyz; NeighListKokkos(class LAMMPS *lmp): - NeighList(lmp) {_stride = 1; maxneighs = 16;}; - ~NeighListKokkos() {stencil = NULL; numneigh = NULL; ilist = NULL;}; + NeighList(lmp) {_stride = 1; maxneighs = 16; kokkos = 1; maxatoms = 0; + execution_space = ExecutionSpaceFromDevice::space; + }; + ~NeighListKokkos() {numneigh = NULL; ilist = NULL;}; KOKKOS_INLINE_FUNCTION AtomNeighbors get_neighbors(const int &i) const { @@ -99,7 +97,8 @@ public: int& num_neighs(const int & i) const { return d_numneigh(i); } - void stencil_allocate(int smax, int style); + private: + int maxatoms; }; } diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index 31fa1859f9..8f334415af 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -1,4 +1,4 @@ -;/* ---------------------------------------------------------------------- +/* ---------------------------------------------------------------------- LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator http://lammps.sandia.gov, Sandia National Laboratories Steve Plimpton, sjplimp@sandia.gov @@ -26,6 +26,10 @@ #include "angle.h" #include "dihedral.h" #include "improper.h" +#include "style_nbin.h" +#include "style_nstencil.h" +#include "style_npair.h" +#include "style_ntopo.h" using namespace LAMMPS_NS; @@ -36,18 +40,11 @@ enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp NeighborKokkos::NeighborKokkos(LAMMPS *lmp) : Neighbor(lmp), neighbond_host(lmp),neighbond_device(lmp) { - atoms_per_bin = 16; - - nlist_host = 0; - lists_host = NULL; - pair_build_host = NULL; - stencil_create_host = NULL; - nlist_device = 0; - lists_device = NULL; - pair_build_device = NULL; - stencil_create_device = NULL; - device_flag = 0; + bondlist = NULL; + anglelist = NULL; + dihedrallist = NULL; + improperlist = NULL; } /* ---------------------------------------------------------------------- */ @@ -58,14 +55,6 @@ NeighborKokkos::~NeighborKokkos() memory->destroy_kokkos(k_cutneighsq,cutneighsq); cutneighsq = NULL; - for (int i = 0; i < nlist_host; i++) delete lists_host[i]; - delete [] lists_host; - for (int i = 0; i < nlist_device; i++) delete lists_device[i]; - delete [] lists_device; - - delete [] pair_build_device; - delete [] pair_build_host; - memory->destroy_kokkos(k_ex_type,ex_type); memory->destroy_kokkos(k_ex1_type,ex1_type); memory->destroy_kokkos(k_ex2_type,ex2_type); @@ -89,6 +78,11 @@ void NeighborKokkos::init() { atomKK = (AtomKokkos *) atom; Neighbor::init(); + + // 1st time allocation of xhold + + if (dist_check) + xhold = DAT::tdual_x_array("neigh:xhold",maxhold); } /* ---------------------------------------------------------------------- */ @@ -101,158 +95,16 @@ void NeighborKokkos::init_cutneighsq_kokkos(int n) /* ---------------------------------------------------------------------- */ -int NeighborKokkos::init_lists_kokkos() -{ - int i; - - for (i = 0; i < nlist_host; i++) delete lists_host[i]; - delete [] lists_host; - delete [] pair_build_host; - delete [] stencil_create_host; - nlist_host = 0; - - for (i = 0; i < nlist_device; i++) delete lists_device[i]; - delete [] lists_device; - delete [] pair_build_device; - delete [] stencil_create_device; - nlist_device = 0; - - nlist = 0; - for (i = 0; i < nrequest; i++) { - if (requests[i]->kokkos_device) nlist_device++; - else if (requests[i]->kokkos_host) nlist_host++; - else nlist++; - } - - lists_host = new NeighListKokkos*[nrequest]; - pair_build_host = new PairPtrHost[nrequest]; - stencil_create_host = new StencilPtrHost[nrequest]; - for (i = 0; i < nrequest; i++) { - lists_host[i] = NULL; - pair_build_host[i] = NULL; - stencil_create_host[i] = NULL; - } - - for (i = 0; i < nrequest; i++) { - if (!requests[i]->kokkos_host) continue; - lists_host[i] = new NeighListKokkos(lmp); - lists_host[i]->index = i; - lists_host[i]->dnum = requests[i]->dnum; - if (requests[i]->pair) { - Pair *pair = (Pair *) requests[i]->requestor; - pair->init_list(requests[i]->id,lists_host[i]); - } - if (requests[i]->fix) { - Fix *fix = (Fix *) requests[i]->requestor; - fix->init_list(requests[i]->id,lists_host[i]); - } - } - - lists_device = new NeighListKokkos*[nrequest]; - pair_build_device = new PairPtrDevice[nrequest]; - stencil_create_device = new StencilPtrDevice[nrequest]; - for (i = 0; i < nrequest; i++) { - lists_device[i] = NULL; - pair_build_device[i] = NULL; - stencil_create_device[i] = NULL; - } - - for (i = 0; i < nrequest; i++) { - if (!requests[i]->kokkos_device) continue; - lists_device[i] = new NeighListKokkos(lmp); - lists_device[i]->index = i; - lists_device[i]->dnum = requests[i]->dnum; - if (requests[i]->pair) { - Pair *pair = (Pair *) requests[i]->requestor; - pair->init_list(requests[i]->id,lists_device[i]); - } - if (requests[i]->fix) { - Fix *fix = (Fix *) requests[i]->requestor; - fix->init_list(requests[i]->id,lists_device[i]); - } - } - - // 1st time allocation of xhold - - if (dist_check) - xhold = DAT::tdual_x_array("neigh:xhold",maxhold); - - // return # of non-Kokkos lists - - return nlist; -} - -/* ---------------------------------------------------------------------- */ - -void NeighborKokkos::init_list_flags1_kokkos(int i) +void NeighborKokkos::create_kokkos_list(int i) { if (style != BIN) error->all(FLERR,"KOKKOS package only supports 'bin' neighbor lists"); - if (lists_host[i]) { - lists_host[i]->buildflag = 1; - if (pair_build_host[i] == NULL) lists_host[i]->buildflag = 0; - if (requests[i]->occasional) lists_host[i]->buildflag = 0; - - lists_host[i]->growflag = 1; - if (requests[i]->copy) lists_host[i]->growflag = 0; - - lists_host[i]->stencilflag = 1; - if (style == NSQ) lists_host[i]->stencilflag = 0; - if (stencil_create[i] == NULL) lists_host[i]->stencilflag = 0; - - lists_host[i]->ghostflag = 0; - if (requests[i]->ghost) lists_host[i]->ghostflag = 1; - if (requests[i]->ghost && !requests[i]->occasional) anyghostlist = 1; - } - - if (lists_device[i]) { - lists_device[i]->buildflag = 1; - if (pair_build_device[i] == NULL) lists_device[i]->buildflag = 0; - if (requests[i]->occasional) lists_device[i]->buildflag = 0; - - lists_device[i]->growflag = 1; - if (requests[i]->copy) lists_device[i]->growflag = 0; - - lists_device[i]->stencilflag = 1; - if (style == NSQ) lists_device[i]->stencilflag = 0; - if (stencil_create[i] == NULL) lists_device[i]->stencilflag = 0; - - lists_device[i]->ghostflag = 0; - if (requests[i]->ghost) lists_device[i]->ghostflag = 1; - if (requests[i]->ghost && !requests[i]->occasional) anyghostlist = 1; - } -} - -/* ---------------------------------------------------------------------- */ - -void NeighborKokkos::init_list_flags2_kokkos(int i) -{ - if (lists_host[i]) { - if (lists_host[i]->buildflag) blist[nblist++] = i; - if (lists_host[i]->growflag && requests[i]->occasional == 0) - glist[nglist++] = i; - if (lists_host[i]->stencilflag && requests[i]->occasional == 0) - slist[nslist++] = i; - } - - if (lists_device[i]) { - if (lists_device[i]->buildflag) blist[nblist++] = i; - if (lists_device[i]->growflag && requests[i]->occasional == 0) - glist[nglist++] = i; - if (lists_device[i]->stencilflag && requests[i]->occasional == 0) - slist[nslist++] = i; - } -} - -/* ---------------------------------------------------------------------- */ - -void NeighborKokkos::init_list_grow_kokkos(int i) -{ - if (lists_host[i]!=NULL && lists_host[i]->growflag) - lists_host[i]->grow(maxatom); - if (lists_device[i]!=NULL && lists_device[i]->growflag) - lists_device[i]->grow(maxatom); + if (requests[i]->kokkos_device) { + lists[i] = new NeighListKokkos(lmp); + device_flag = 1; + } else if (requests[i]->kokkos_host) + lists[i] = new NeighListKokkos(lmp); } /* ---------------------------------------------------------------------- */ @@ -281,49 +133,6 @@ void NeighborKokkos::init_ex_mol_bit_kokkos() k_ex_mol_bit.modify(); } -/* ---------------------------------------------------------------------- */ - -void NeighborKokkos::choose_build(int index, NeighRequest *rq) -{ - if (rq->kokkos_host != 0) { - PairPtrHost pb = NULL; - if (rq->ghost) { - if (rq->full) { - if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; - else pb = &NeighborKokkos::full_bin_kokkos; - } - else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; - } else { - if (rq->full) { - if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; - else pb = &NeighborKokkos::full_bin_kokkos; - } - else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; - } - pair_build_host[index] = pb; - } - if (rq->kokkos_device != 0) { - PairPtrDevice pb = NULL; - if (rq->ghost) { - if (rq->full) { - if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; - else pb = &NeighborKokkos::full_bin_kokkos; - } - else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; - } else { - if (rq->full) { - if (rq->full_cluster) pb = &NeighborKokkos::full_bin_cluster_kokkos; - else pb = &NeighborKokkos::full_bin_kokkos; - } - else if (rq->half) pb = &NeighborKokkos::full_bin_kokkos; - } - pair_build_device[index] = pb; - return; - } - - Neighbor::choose_build(index,rq); -} - /* ---------------------------------------------------------------------- if any atom moved trigger distance (half of neighbor skin) return 1 shrink trigger distance if box size has changed @@ -337,7 +146,7 @@ void NeighborKokkos::choose_build(int index, NeighRequest *rq) int NeighborKokkos::check_distance() { - if (nlist_device) + if (device_flag) check_distance_kokkos(); else check_distance_kokkos(); @@ -417,7 +226,7 @@ void NeighborKokkos::operator()(TagNeighborCheckDistance, const int void NeighborKokkos::build(int topoflag) { - if (nlist_device) + if (device_flag) build_kokkos(topoflag); else build_kokkos(topoflag); @@ -428,18 +237,25 @@ void NeighborKokkos::build_kokkos(int topoflag) { typedef DeviceType device_type; - int i; + int i,m; ago = 0; ncalls++; lastcall = update->ntimestep; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + // check that using special bond flags will not overflow neigh lists + + if (nall > NEIGHMASK) + error->one(FLERR,"Too many local+ghost atoms for neighbor list"); + // store current atom positions and box size if needed if (dist_check) { atomKK->sync(ExecutionSpaceFromDevice::space,X_MASK); x = atomKK->k_x; - int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; int maxhold_kokkos = xhold.view().dimension_0(); if (atom->nmax > maxhold || maxhold_kokkos < maxhold) { @@ -471,54 +287,33 @@ void NeighborKokkos::build_kokkos(int topoflag) } } - // if any lists store neighbors of ghosts: - // invoke grow() if nlocal+nghost exceeds previous list size - // else only invoke grow() if nlocal exceeds previous list size - // only for lists with growflag set and which are perpetual (glist) + // bin atoms for all NBin instances + // not just NBin associated with perpetual lists + // b/c cannot wait to bin occasional lists in build_one() call + // if bin then, atoms may have moved outside of proc domain & bin extent, + // leading to errors or even a crash - if (anyghostlist && atom->nmax > maxatom) { - maxatom = atom->nmax; - for (i = 0; i < nglist; i++) - if (lists[glist[i]]) lists[glist[i]]->grow(maxatom); - else init_list_grow_kokkos(glist[i]); - } else if (atom->nmax > maxatom) { - maxatom = atom->nmax; - for (i = 0; i < nglist; i++) - if (lists[glist[i]]) lists[glist[i]]->grow(maxatom); - else init_list_grow_kokkos(glist[i]); - } - - // extend atom bin list if necessary - - if (style != NSQ && atom->nmax > maxbin) { - maxbin = atom->nmax; - memory->destroy(bins); - memory->create(bins,maxbin,"bins"); - } - - // check that using special bond flags will not overflow neigh lists - - if (atom->nlocal+atom->nghost > NEIGHMASK) - error->one(FLERR,"Too many local+ghost atoms for neighbor list"); - - // invoke building of pair and molecular topology neighbor lists - // only for pairwise lists with buildflag set - // blist is for standard neigh lists, otherwise is a Kokkos list - - for (i = 0; i < nblist; i++) { - if (lists[blist[i]]) { - atomKK->sync(Host,ALL_MASK); - (this->*pair_build[blist[i]])(lists[blist[i]]); - } else { - if (lists_host[blist[i]]) - (this->*pair_build_host[blist[i]])(lists_host[blist[i]]); - else if (lists_device[blist[i]]) - (this->*pair_build_device[blist[i]])(lists_device[blist[i]]); + if (style != NSQ) { + for (int i = 0; i < nbin; i++) { + neigh_bin[i]->bin_atoms_setup(nall); + neigh_bin[i]->bin_atoms(); } } - if (atom->molecular && topoflag) - build_topology_kokkos(); + // build pairwise lists for all perpetual NPair/NeighList + // grow() with nlocal/nall args so that only realloc if have to + + atomKK->sync(Host,ALL_MASK); + for (i = 0; i < npair_perpetual; i++) { + m = plist[i]; + lists[m]->grow(nlocal,nall); + neigh_pair[m]->build_setup(); + neigh_pair[m]->build(lists[m]); + } + + // build topology lists for bonds/angles/etc + + if (atom->molecular && topoflag) build_topology(); } template @@ -532,26 +327,6 @@ void NeighborKokkos::operator()(TagNeighborXhold, const int &i) cons /* ---------------------------------------------------------------------- */ -void NeighborKokkos::setup_bins_kokkos(int i) -{ - if (lists_host[slist[i]]) { - lists_host[slist[i]]->stencil_allocate(smax,style); - (this->*stencil_create[slist[i]])(lists_host[slist[i]],sx,sy,sz); - } else if (lists_device[slist[i]]) { - lists_device[slist[i]]->stencil_allocate(smax,style); - (this->*stencil_create[slist[i]])(lists_device[slist[i]],sx,sy,sz); - } - - //if (i < nslist-1) return; // this won't work if a non-kokkos neighbor list is last - - if (maxhead > k_bins.d_view.dimension_0()) { - k_bins = DAT::tdual_int_2d("Neighbor::d_bins",maxhead,atoms_per_bin); - k_bincount = DAT::tdual_int_1d("Neighbor::d_bincount",maxhead); - } -} - -/* ---------------------------------------------------------------------- */ - void NeighborKokkos::modify_ex_type_grow_kokkos(){ memory->grow_kokkos(k_ex1_type,ex1_type,maxex_type,"neigh:ex1_type"); k_ex1_type.modify(); @@ -575,8 +350,8 @@ void NeighborKokkos::modify_mol_group_grow_kokkos(){ /* ---------------------------------------------------------------------- */ -void NeighborKokkos::init_topology_kokkos() { - if (nlist_device) { +void NeighborKokkos::init_topology() { + if (device_flag) { neighbond_device.init_topology_kk(); } else { neighbond_host.init_topology_kk(); @@ -588,8 +363,8 @@ void NeighborKokkos::init_topology_kokkos() { normally built with pair lists, but USER-CUDA separates them ------------------------------------------------------------------------- */ -void NeighborKokkos::build_topology_kokkos() { - if (nlist_device) { +void NeighborKokkos::build_topology() { + if (device_flag) { neighbond_device.build_topology_kk(); k_bondlist = neighbond_device.k_bondlist; @@ -637,7 +412,3 @@ void NeighborKokkos::build_topology_kokkos() { k_improperlist.modify(); } } - -// include to trigger instantiation of templated functions - -#include "neigh_full_kokkos.h" diff --git a/src/KOKKOS/neighbor_kokkos.h b/src/KOKKOS/neighbor_kokkos.h index 8c097139a7..244de19dce 100644 --- a/src/KOKKOS/neighbor_kokkos.h +++ b/src/KOKKOS/neighbor_kokkos.h @@ -22,316 +22,6 @@ namespace LAMMPS_NS { -template -class NeighborKokkosExecute -{ - typedef ArrayTypes AT; - - public: - NeighListKokkos neigh_list; - const typename AT::t_xfloat_2d_randomread cutneighsq; - const typename AT::t_int_1d bincount; - const typename AT::t_int_1d_const c_bincount; - typename AT::t_int_2d bins; - typename AT::t_int_2d_const c_bins; - const typename AT::t_x_array_randomread x; - const typename AT::t_int_1d_const type,mask,molecule; - - const typename AT::t_tagint_1d_const tag; - const typename AT::t_tagint_2d_const special; - const typename AT::t_int_2d_const nspecial; - const int molecular; - int moltemplate; - - int special_flag[4]; - - const int nbinx,nbiny,nbinz; - const int mbinx,mbiny,mbinz; - const int mbinxlo,mbinylo,mbinzlo; - const X_FLOAT bininvx,bininvy,bininvz; - X_FLOAT bboxhi[3],bboxlo[3]; - - const int nlocal; - - const int exclude; - - const int nex_type; - const int maxex_type; - const typename AT::t_int_1d_const ex1_type,ex2_type; - const typename AT::t_int_2d_const ex_type; - - const int nex_group; - const int maxex_group; - const typename AT::t_int_1d_const ex1_group,ex2_group; - const typename AT::t_int_1d_const ex1_bit,ex2_bit; - - const int nex_mol; - const int maxex_mol; - const typename AT::t_int_1d_const ex_mol_group; - const typename AT::t_int_1d_const ex_mol_bit; - - typename AT::t_int_scalar resize; - typename AT::t_int_scalar new_maxneighs; - typename ArrayTypes::t_int_scalar h_resize; - typename ArrayTypes::t_int_scalar h_new_maxneighs; - - const int xperiodic, yperiodic, zperiodic; - const int xprd_half, yprd_half, zprd_half; - - NeighborKokkosExecute( - const NeighListKokkos &_neigh_list, - const typename AT::t_xfloat_2d_randomread &_cutneighsq, - const typename AT::t_int_1d &_bincount, - const typename AT::t_int_2d &_bins, - const int _nlocal, - const typename AT::t_x_array_randomread &_x, - const typename AT::t_int_1d_const &_type, - const typename AT::t_int_1d_const &_mask, - const typename AT::t_int_1d_const &_molecule, - const typename AT::t_tagint_1d_const &_tag, - const typename AT::t_tagint_2d_const &_special, - const typename AT::t_int_2d_const &_nspecial, - const int &_molecular, - const int & _nbinx,const int & _nbiny,const int & _nbinz, - const int & _mbinx,const int & _mbiny,const int & _mbinz, - const int & _mbinxlo,const int & _mbinylo,const int & _mbinzlo, - const X_FLOAT &_bininvx,const X_FLOAT &_bininvy,const X_FLOAT &_bininvz, - const int & _exclude,const int & _nex_type,const int & _maxex_type, - const typename AT::t_int_1d_const & _ex1_type, - const typename AT::t_int_1d_const & _ex2_type, - const typename AT::t_int_2d_const & _ex_type, - const int & _nex_group,const int & _maxex_group, - const typename AT::t_int_1d_const & _ex1_group, - const typename AT::t_int_1d_const & _ex2_group, - const typename AT::t_int_1d_const & _ex1_bit, - const typename AT::t_int_1d_const & _ex2_bit, - const int & _nex_mol,const int & _maxex_mol, - const typename AT::t_int_1d_const & _ex_mol_group, - const typename AT::t_int_1d_const & _ex_mol_bit, - const X_FLOAT *_bboxhi, const X_FLOAT* _bboxlo, - const int & _xperiodic, const int & _yperiodic, const int & _zperiodic, - const int & _xprd_half, const int & _yprd_half, const int & _zprd_half): - neigh_list(_neigh_list), cutneighsq(_cutneighsq), - bincount(_bincount),c_bincount(_bincount),bins(_bins),c_bins(_bins), - nlocal(_nlocal), - x(_x),type(_type),mask(_mask),molecule(_molecule), - tag(_tag),special(_special),nspecial(_nspecial),molecular(_molecular), - nbinx(_nbinx),nbiny(_nbiny),nbinz(_nbinz), - mbinx(_mbinx),mbiny(_mbiny),mbinz(_mbinz), - mbinxlo(_mbinxlo),mbinylo(_mbinylo),mbinzlo(_mbinzlo), - bininvx(_bininvx),bininvy(_bininvy),bininvz(_bininvz), - exclude(_exclude),nex_type(_nex_type),maxex_type(_maxex_type), - ex1_type(_ex1_type),ex2_type(_ex2_type),ex_type(_ex_type), - nex_group(_nex_group),maxex_group(_maxex_group), - ex1_group(_ex1_group),ex2_group(_ex2_group), - ex1_bit(_ex1_bit),ex2_bit(_ex2_bit),nex_mol(_nex_mol),maxex_mol(_maxex_mol), - ex_mol_group(_ex_mol_group),ex_mol_bit(_ex_mol_bit), - xperiodic(_xperiodic),yperiodic(_yperiodic),zperiodic(_zperiodic), - xprd_half(_xprd_half),yprd_half(_yprd_half),zprd_half(_zprd_half){ - - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - bboxlo[0] = _bboxlo[0]; bboxlo[1] = _bboxlo[1]; bboxlo[2] = _bboxlo[2]; - bboxhi[0] = _bboxhi[0]; bboxhi[1] = _bboxhi[1]; bboxhi[2] = _bboxhi[2]; - - resize = typename AT::t_int_scalar("NeighborKokkosFunctor::resize"); -#ifndef KOKKOS_USE_CUDA_UVM - h_resize = Kokkos::create_mirror_view(resize); -#else - h_resize = resize; -#endif - h_resize() = 1; - new_maxneighs = typename AT:: - t_int_scalar("NeighborKokkosFunctor::new_maxneighs"); -#ifndef KOKKOS_USE_CUDA_UVM - h_new_maxneighs = Kokkos::create_mirror_view(new_maxneighs); -#else - h_new_maxneighs = new_maxneighs; -#endif - h_new_maxneighs() = neigh_list.maxneighs; - }; - - ~NeighborKokkosExecute() {neigh_list.clean_copy();}; - - template - KOKKOS_FUNCTION - void build_Item(const int &i) const; - - template - KOKKOS_FUNCTION - void build_Item_Ghost(const int &i) const; - - template - KOKKOS_FUNCTION - void build_cluster_Item(const int &i) const; - -#ifdef KOKKOS_HAVE_CUDA - template - __device__ inline - void build_ItemCuda(typename Kokkos::TeamPolicy::member_type dev) const; -#endif - - KOKKOS_INLINE_FUNCTION - void binatomsItem(const int &i) const; - - KOKKOS_INLINE_FUNCTION - int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z) const - { - int ix,iy,iz; - - if (x >= bboxhi[0]) - ix = static_cast ((x-bboxhi[0])*bininvx) + nbinx; - else if (x >= bboxlo[0]) { - ix = static_cast ((x-bboxlo[0])*bininvx); - ix = MIN(ix,nbinx-1); - } else - ix = static_cast ((x-bboxlo[0])*bininvx) - 1; - - if (y >= bboxhi[1]) - iy = static_cast ((y-bboxhi[1])*bininvy) + nbiny; - else if (y >= bboxlo[1]) { - iy = static_cast ((y-bboxlo[1])*bininvy); - iy = MIN(iy,nbiny-1); - } else - iy = static_cast ((y-bboxlo[1])*bininvy) - 1; - - if (z >= bboxhi[2]) - iz = static_cast ((z-bboxhi[2])*bininvz) + nbinz; - else if (z >= bboxlo[2]) { - iz = static_cast ((z-bboxlo[2])*bininvz); - iz = MIN(iz,nbinz-1); - } else - iz = static_cast ((z-bboxlo[2])*bininvz) - 1; - - return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); - } - - KOKKOS_INLINE_FUNCTION - int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z, int* i) const - { - int ix,iy,iz; - - if (x >= bboxhi[0]) - ix = static_cast ((x-bboxhi[0])*bininvx) + nbinx; - else if (x >= bboxlo[0]) { - ix = static_cast ((x-bboxlo[0])*bininvx); - ix = MIN(ix,nbinx-1); - } else - ix = static_cast ((x-bboxlo[0])*bininvx) - 1; - - if (y >= bboxhi[1]) - iy = static_cast ((y-bboxhi[1])*bininvy) + nbiny; - else if (y >= bboxlo[1]) { - iy = static_cast ((y-bboxlo[1])*bininvy); - iy = MIN(iy,nbiny-1); - } else - iy = static_cast ((y-bboxlo[1])*bininvy) - 1; - - if (z >= bboxhi[2]) - iz = static_cast ((z-bboxhi[2])*bininvz) + nbinz; - else if (z >= bboxlo[2]) { - iz = static_cast ((z-bboxlo[2])*bininvz); - iz = MIN(iz,nbinz-1); - } else - iz = static_cast ((z-bboxlo[2])*bininvz) - 1; - - i[0] = ix - mbinxlo; - i[1] = iy - mbinylo; - i[2] = iz - mbinzlo; - - return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); - } - - KOKKOS_INLINE_FUNCTION - int exclusion(const int &i,const int &j, const int &itype,const int &jtype) const; - - KOKKOS_INLINE_FUNCTION - int find_special(const int &i, const int &j) const; - - KOKKOS_INLINE_FUNCTION - int minimum_image_check(double dx, double dy, double dz) const { - if (xperiodic && fabs(dx) > xprd_half) return 1; - if (yperiodic && fabs(dy) > yprd_half) return 1; - if (zperiodic && fabs(dz) > zprd_half) return 1; - return 0; - } - -}; - -template -struct NeighborKokkosBinAtomsFunctor { - typedef Device device_type; - - const NeighborKokkosExecute c; - - NeighborKokkosBinAtomsFunctor(const NeighborKokkosExecute &_c): - c(_c) {}; - ~NeighborKokkosBinAtomsFunctor() {} - KOKKOS_INLINE_FUNCTION - void operator() (const int & i) const { - c.binatomsItem(i); - } -}; - -template -struct NeighborKokkosBuildFunctor { - typedef Device device_type; - - const NeighborKokkosExecute c; - const size_t sharedsize; - - NeighborKokkosBuildFunctor(const NeighborKokkosExecute &_c, - const size_t _sharedsize):c(_c), - sharedsize(_sharedsize) {}; - - KOKKOS_INLINE_FUNCTION - void operator() (const int & i) const { - c.template build_Item(i); - } -#ifdef KOKKOS_HAVE_CUDA - KOKKOS_INLINE_FUNCTION - void operator() (typename Kokkos::TeamPolicy::member_type dev) const { - c.template build_ItemCuda(dev); - } - size_t shmem_size(const int team_size) const { (void) team_size; return sharedsize; } -#endif -}; - -template -struct NeighborKokkosBuildFunctorGhost { - typedef Device device_type; - - const NeighborKokkosExecute c; - const size_t sharedsize; - - NeighborKokkosBuildFunctorGhost(const NeighborKokkosExecute &_c, - const size_t _sharedsize):c(_c), - sharedsize(_sharedsize) {}; - - KOKKOS_INLINE_FUNCTION - void operator() (const int & i) const { - c.template build_Item_Ghost(i); - } -}; - -template -struct NeighborClusterKokkosBuildFunctor { - typedef Device device_type; - - const NeighborKokkosExecute c; - const size_t sharedsize; - - NeighborClusterKokkosBuildFunctor(const NeighborKokkosExecute &_c, - const size_t _sharedsize):c(_c), - sharedsize(_sharedsize) {}; - - KOKKOS_INLINE_FUNCTION - void operator() (const int & i) const { - c.template build_cluster_Item(i); - } -}; - template struct TagNeighborCheckDistance{}; @@ -342,24 +32,11 @@ class NeighborKokkos : public Neighbor { public: typedef int value_type; - - - int nlist_host; // pairwise neighbor lists on Host - NeighListKokkos **lists_host; - int nlist_device; // pairwise neighbor lists on Device - NeighListKokkos **lists_device; - - NeighBondKokkos neighbond_host; - NeighBondKokkos neighbond_device; - - DAT::tdual_int_2d k_bondlist; - DAT::tdual_int_2d k_anglelist; - DAT::tdual_int_2d k_dihedrallist; - DAT::tdual_int_2d k_improperlist; - NeighborKokkos(class LAMMPS *); ~NeighborKokkos(); void init(); + void init_topology(); + void build_topology(); template KOKKOS_INLINE_FUNCTION @@ -369,11 +46,7 @@ class NeighborKokkos : public Neighbor { KOKKOS_INLINE_FUNCTION void operator()(TagNeighborXhold, const int&) const; - private: - int atoms_per_bin; DAT::tdual_xfloat_2d k_cutneighsq; - DAT::tdual_int_1d k_bincount; - DAT::tdual_int_2d k_bins; DAT::tdual_int_1d k_ex1_type,k_ex2_type; DAT::tdual_int_2d k_ex_type; @@ -382,6 +55,16 @@ class NeighborKokkos : public Neighbor { DAT::tdual_int_1d k_ex_mol_group; DAT::tdual_int_1d k_ex_mol_bit; + NeighBondKokkos neighbond_host; + NeighBondKokkos neighbond_device; + + DAT::tdual_int_2d k_bondlist; + DAT::tdual_int_2d k_anglelist; + DAT::tdual_int_2d k_dihedrallist; + DAT::tdual_int_2d k_improperlist; + + private: + DAT::tdual_x_array x; DAT::tdual_x_array xhold; @@ -389,14 +72,10 @@ class NeighborKokkos : public Neighbor { int device_flag; void init_cutneighsq_kokkos(int); - int init_lists_kokkos(); - void init_list_flags1_kokkos(int); - void init_list_flags2_kokkos(int); - void init_list_grow_kokkos(int); + void create_kokkos_list(int); void init_ex_type_kokkos(int); void init_ex_bit_kokkos(); void init_ex_mol_bit_kokkos(); - void choose_build(int, NeighRequest *); virtual int check_distance(); template int check_distance_kokkos(); virtual void build(int); @@ -405,27 +84,6 @@ class NeighborKokkos : public Neighbor { void modify_ex_type_grow_kokkos(); void modify_ex_group_grow_kokkos(); void modify_mol_group_grow_kokkos(); - void init_topology_kokkos(); - void build_topology_kokkos(); - - typedef void (NeighborKokkos::*PairPtrHost) - (class NeighListKokkos *); - PairPtrHost *pair_build_host; - typedef void (NeighborKokkos::*PairPtrDevice) - (class NeighListKokkos *); - PairPtrDevice *pair_build_device; - - template - void full_bin_kokkos(NeighListKokkos *list); - template - void full_bin_cluster_kokkos(NeighListKokkos *list); - - typedef void (NeighborKokkos::*StencilPtrHost) - (class NeighListKokkos *, int, int, int); - StencilPtrHost *stencil_create_host; - typedef void (NeighborKokkos::*StencilPtrDevice) - (class NeighListKokkos *, int, int, int); - StencilPtrDevice *stencil_create_device; }; } diff --git a/src/KOKKOS/npair_copy_kokkos.cpp b/src/KOKKOS/npair_copy_kokkos.cpp new file mode 100644 index 0000000000..6835d8c1b5 --- /dev/null +++ b/src/KOKKOS/npair_copy_kokkos.cpp @@ -0,0 +1,62 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_copy_kokkos.h" +#include "neighbor.h" +#include "neigh_list_kokkos.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; + +/* ---------------------------------------------------------------------- */ + +template +NPairCopyKokkos::NPairCopyKokkos(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + create list which is simply a copy of parent list +------------------------------------------------------------------------- */ + +template +void NPairCopyKokkos::build(NeighList *list) +{ + NeighList *listcopy = list->listcopy; + + list->inum = listcopy->inum; + list->gnum = listcopy->gnum; + list->ilist = listcopy->ilist; + list->numneigh = listcopy->numneigh; + list->firstneigh = listcopy->firstneigh; + list->firstdouble = listcopy->firstdouble; + list->ipage = listcopy->ipage; + list->dpage = listcopy->dpage; + + NeighListKokkos* list_kk = (NeighListKokkos*) list; + NeighListKokkos* listcopy_kk = (NeighListKokkos*) list->listcopy; + + list_kk->d_ilist = listcopy_kk->d_ilist; + list_kk->d_numneigh = listcopy_kk->d_numneigh; + list_kk->d_neighbors = listcopy_kk->d_neighbors; +} + +namespace LAMMPS_NS { +template class NPairCopyKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class NPairCopyKokkos; +#endif +} diff --git a/src/KOKKOS/npair_copy_kokkos.h b/src/KOKKOS/npair_copy_kokkos.h new file mode 100644 index 0000000000..84eb10b204 --- /dev/null +++ b/src/KOKKOS/npair_copy_kokkos.h @@ -0,0 +1,48 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(copy/kk/device, + NPairCopyKokkos, + NP_COPY | NP_KOKKOS_DEVICE) + +NPairStyle(copy/kk/host, + NPairCopyKokkos, + NP_COPY | NP_KOKKOS_HOST) + +#else + +#ifndef LMP_NPAIR_COPY_KOKKOS_H +#define LMP_NPAIR_COPY_KOKKOS_H + +#include "npair.h" + +namespace LAMMPS_NS { + +template +class NPairCopyKokkos : public NPair { + public: + NPairCopyKokkos(class LAMMPS *); + ~NPairCopyKokkos() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/neigh_full_kokkos.h b/src/KOKKOS/npair_kokkos.cpp similarity index 67% rename from src/KOKKOS/neigh_full_kokkos.h rename to src/KOKKOS/npair_kokkos.cpp index 9125b5fbe2..fd32cd463e 100644 --- a/src/KOKKOS/neigh_full_kokkos.h +++ b/src/KOKKOS/npair_kokkos.cpp @@ -11,17 +11,105 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "npair_kokkos.h" #include "atom_kokkos.h" #include "atom_masks.h" #include "domain_kokkos.h" +#include "neighbor_kokkos.h" +#include "nbin_kokkos.h" +#include "nstencil.h" +#include "force.h" namespace LAMMPS_NS { /* ---------------------------------------------------------------------- */ template -void NeighborKokkos::full_bin_kokkos(NeighListKokkos *list) +NPairKokkos::NPairKokkos(LAMMPS *lmp) : NPair(lmp) { + +} + +/* ---------------------------------------------------------------------- + copy needed info from Neighbor class to this build class + ------------------------------------------------------------------------- */ + +template +void NPairKokkos::copy_neighbor_info() { + NPair::copy_neighbor_info(); + + NeighborKokkos* neighborKK = (NeighborKokkos*) neighbor; + + // general params + + newton_pair = force->newton_pair; + k_cutneighsq = neighborKK->k_cutneighsq; + + // exclusion info + + k_ex1_type = neighborKK->k_ex1_type; + k_ex2_type = neighborKK->k_ex2_type; + k_ex_type = neighborKK->k_ex_type; + k_ex1_group = neighborKK->k_ex1_group; + k_ex2_group = neighborKK->k_ex2_group; + k_ex1_bit = neighborKK->k_ex1_bit; + k_ex2_bit = neighborKK->k_ex2_bit; + k_ex_mol_group = neighborKK->k_ex_mol_group; + k_ex_mol_bit = neighborKK->k_ex_mol_bit; +} + +/* ---------------------------------------------------------------------- + copy per-atom and per-bin vectors from NBin class to this build class + ------------------------------------------------------------------------- */ + +template +void NPairKokkos::copy_bin_info() +{ + NPair::copy_bin_info(); + + NBinKokkos* nbKK = (NBinKokkos*) nb; + + atoms_per_bin = nbKK->atoms_per_bin; + k_bincount = nbKK->k_bincount; + k_bins = nbKK->k_bins; +} + +/* ---------------------------------------------------------------------- + copy needed info from NStencil class to this build class + ------------------------------------------------------------------------- */ + +template +void NPairKokkos::copy_stencil_info() +{ + NPair::copy_stencil_info(); + + nstencil = ns->nstencil; + + int maxstencil = ns->get_maxstencil(); + + k_stencil = DAT::tdual_int_1d("neighlist:stencil",maxstencil); + for (int k = 0; k < maxstencil; k++) + k_stencil.h_view(k) = ns->stencil[k]; + k_stencil.modify(); + k_stencil.sync(); + if (GHOST) { + k_stencilxyz = DAT::tdual_int_1d_3("neighlist:stencilxyz",maxstencil); + for (int k = 0; k < maxstencil; k++) { + k_stencilxyz.h_view(k,0) = ns->stencilxyz[k][0]; + k_stencilxyz.h_view(k,1) = ns->stencilxyz[k][1]; + k_stencilxyz.h_view(k,2) = ns->stencilxyz[k][2]; + } + k_stencilxyz.modify(); + k_stencilxyz.sync(); + } +} + +/* ---------------------------------------------------------------------- */ + +template +void NPairKokkos::build(NeighList *list_) +{ + NeighListKokkos* list = (NeighListKokkos*) list_; const int nlocal = includegroup?atom->nfirst:atom->nlocal; int nall = nlocal; if (GHOST) @@ -32,7 +120,11 @@ void NeighborKokkos::full_bin_kokkos(NeighListKokkos *list) data(*list, k_cutneighsq.view(), k_bincount.view(), - k_bins.view(),nlocal, + k_bins.view(), + nstencil, + k_stencil.view(), + k_stencilxyz.view(), + nlocal, atomKK->k_x.view(), atomKK->k_type.view(), atomKK->k_mask.view(), @@ -43,16 +135,16 @@ void NeighborKokkos::full_bin_kokkos(NeighListKokkos *list) atomKK->molecular, nbinx,nbiny,nbinz,mbinx,mbiny,mbinz,mbinxlo,mbinylo,mbinzlo, bininvx,bininvy,bininvz, - exclude, nex_type,maxex_type, + exclude, nex_type, k_ex1_type.view(), k_ex2_type.view(), k_ex_type.view(), - nex_group,maxex_group, + nex_group, k_ex1_group.view(), k_ex2_group.view(), k_ex1_bit.view(), k_ex2_bit.view(), - nex_mol, maxex_mol, + nex_mol, k_ex_mol_group.view(), k_ex_mol_bit.view(), bboxhi,bboxlo, @@ -69,40 +161,15 @@ void NeighborKokkos::full_bin_kokkos(NeighListKokkos *list) k_ex2_bit.sync(); k_ex_mol_group.sync(); k_ex_mol_bit.sync(); + k_bincount.sync(), + k_bins.sync(), atomKK->sync(Device,X_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK); - Kokkos::deep_copy(list->d_stencil,list->h_stencil); - if (GHOST) - Kokkos::deep_copy(list->d_stencilxyz,list->h_stencilxyz); data.special_flag[0] = special_flag[0]; data.special_flag[1] = special_flag[1]; data.special_flag[2] = special_flag[2]; data.special_flag[3] = special_flag[3]; - while(data.h_resize() > 0) { - data.h_resize() = 0; - deep_copy(data.resize, data.h_resize); - - MemsetZeroFunctor f_zero; - f_zero.ptr = (void*) k_bincount.view().ptr_on_device(); - Kokkos::parallel_for(mbins, f_zero); - DeviceType::fence(); - - NeighborKokkosBinAtomsFunctor f(data); - - Kokkos::parallel_for(atom->nlocal+atom->nghost, f); - DeviceType::fence(); - - deep_copy(data.h_resize, data.resize); - if(data.h_resize()) { - - atoms_per_bin += 16; - k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin); - data.bins = k_bins.view(); - data.c_bins = data.bins; - } - } - if(list->d_neighbors.dimension_0()d_neighbors = typename ArrayTypes::t_neighbors_2d("neighbors", nall*1.1, list->maxneighs); list->d_numneigh = typename ArrayTypes::t_int_1d("numneigh", nall*1.1); @@ -125,18 +192,18 @@ void NeighborKokkos::full_bin_kokkos(NeighListKokkos *list) #endif if (GHOST) { - NeighborKokkosBuildFunctorGhost f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); + NPairKokkosBuildFunctorGhost f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); Kokkos::parallel_for(nall, f); } else { - if(newton_pair) { - NeighborKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); + if (newton_pair) { + NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); #ifdef KOKKOS_HAVE_CUDA Kokkos::parallel_for(config, f); #else Kokkos::parallel_for(nall, f); #endif } else { - NeighborKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); + NPairKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); #ifdef KOKKOS_HAVE_CUDA Kokkos::parallel_for(config, f); #else @@ -169,24 +236,9 @@ if (GHOST) { /* ---------------------------------------------------------------------- */ -template +template KOKKOS_INLINE_FUNCTION -void NeighborKokkosExecute::binatomsItem(const int &i) const -{ - const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2)); - - const int ac = Kokkos::atomic_fetch_add(&bincount[ibin], (int)1); - if(ac < bins.dimension_1()) { - bins(ibin, ac) = i; - } else { - resize() = 1; - } -} - -/* ---------------------------------------------------------------------- */ -template -KOKKOS_INLINE_FUNCTION -int NeighborKokkosExecute::find_special(const int &i, const int &j) const +int NeighborKokkosExecute::find_special(const int &i, const int &j) const { const int n1 = nspecial(i,0); const int n2 = nspecial(i,1); @@ -214,9 +266,9 @@ int NeighborKokkosExecute::find_special(const int &i, const int &j) cons /* ---------------------------------------------------------------------- */ -template +template KOKKOS_INLINE_FUNCTION -int NeighborKokkosExecute::exclusion(const int &i,const int &j, +int NeighborKokkosExecute::exclusion(const int &i,const int &j, const int &itype,const int &jtype) const { int m; @@ -241,8 +293,8 @@ int NeighborKokkosExecute::exclusion(const int &i,const int &j, /* ---------------------------------------------------------------------- */ -template template -void NeighborKokkosExecute:: +template template +void NeighborKokkosExecute:: build_Item(const int &i) const { /* if necessary, goto next page and add pages */ @@ -261,9 +313,8 @@ void NeighborKokkosExecute:: const int ibin = coord2bin(xtmp, ytmp, ztmp); - const int nstencil = neigh_list.nstencil; - const typename ArrayTypes::t_int_1d_const_um stencil - = neigh_list.d_stencil; + const typename ArrayTypes::t_int_1d_const_um stencil + = d_stencil; // loop over all bins in neighborhood (includes ibin) if(HalfNeigh) @@ -272,8 +323,8 @@ void NeighborKokkosExecute:: const int jtype = type(j); //for same bin as atom i skip j if i==j and skip atoms "below and to the left" if using HalfNeighborlists - if((j == i) || (HalfNeigh && !GhostNewton && (j < i)) || - (HalfNeigh && GhostNewton && ((j < i) || ((j >= nlocal) && + if((j == i) || (HalfNeigh && !Newton && (j < i)) || + (HalfNeigh && Newton && ((j < i) || ((j >= nlocal) && ((x(j, 2) < ztmp) || (x(j, 2) == ztmp && x(j, 1) < ytmp) || (x(j, 2) == ztmp && x(j, 1) == ytmp && x(j, 0) < xtmp))))) ) continue; @@ -312,14 +363,16 @@ void NeighborKokkosExecute:: for(int k = 0; k < nstencil; k++) { const int jbin = ibin + stencil[k]; + // get subview of jbin if(HalfNeigh&&(ibin==jbin)) continue; - //const ArrayTypes::t_int_1d_const_um =Kokkos::subview(bins,jbin,ALL); + //const ArrayTypes::t_int_1d_const_um =Kokkos::subview(bins,jbin,ALL); for(int m = 0; m < c_bincount(jbin); m++) { + const int j = c_bins(jbin,m); const int jtype = type(j); - if(HalfNeigh && !GhostNewton && (j < i)) continue; + if(HalfNeigh && !Newton && (j < i)) continue; if(!HalfNeigh && j==i) continue; if(exclude && exclusion(i,j,itype,jtype)) continue; @@ -331,7 +384,7 @@ void NeighborKokkosExecute:: if(rsq <= cutneighsq(itype,jtype)) { if (molecular) { if (!moltemplate) - which = find_special(i,j); + which = NeighborKokkosExecute::find_special(i,j); /* else if (imol >= 0) */ /* which = find_special(onemols[imol]->special[iatom], */ /* onemols[imol]->nspecial[iatom], */ @@ -364,15 +417,18 @@ void NeighborKokkosExecute:: if(n >= new_maxneighs()) new_maxneighs() = n; } + neigh_list.d_ilist(i) = i; } +/* ---------------------------------------------------------------------- */ + #ifdef KOKKOS_HAVE_CUDA extern __shared__ X_FLOAT sharedmem[]; /* ---------------------------------------------------------------------- */ -template template +template template __device__ inline void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPolicy::member_type dev) const { @@ -429,8 +485,8 @@ void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPoli //for same bin as atom i skip j if i==j and skip atoms "below and to the left" if using halfneighborlists if((j == i) || - (HalfNeigh && !GhostNewton && (j < i)) || - (HalfNeigh && GhostNewton && + (HalfNeigh && !Newton && (j < i)) || + (HalfNeigh && Newton && ((j < i) || ((j >= nlocal) && ((x(j, 2) < ztmp) || (x(j, 2) == ztmp && x(j, 1) < ytmp) || (x(j, 2) == ztmp && x(j, 1) == ytmp && x(j, 0) < xtmp))))) @@ -445,7 +501,7 @@ void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPoli if (molecular) { int which = 0; if (!moltemplate) - which = find_special(i,j); + which = NeighborKokkosExecute::find_special(i,j); /* else if (imol >= 0) */ /* which = find_special(onemols[imol]->special[iatom], */ /* onemols[imol]->nspecial[iatom], */ @@ -472,9 +528,8 @@ void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPoli } __syncthreads(); - const int nstencil = neigh_list.nstencil; const typename ArrayTypes::t_int_1d_const_um stencil - = neigh_list.d_stencil; + = d_stencil; for(int k = 0; k < nstencil; k++) { const int jbin = ibin + stencil[k]; @@ -501,7 +556,7 @@ void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPoli const int jtype = other_x[m + 3 * atoms_per_bin]; //if(HalfNeigh && (j < i)) continue; - if(HalfNeigh && !GhostNewton && (j < i)) continue; + if(HalfNeigh && !Newton && (j < i)) continue; if(!HalfNeigh && j==i) continue; if(exclude && exclusion(i,j,itype,jtype)) continue; @@ -514,7 +569,7 @@ void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPoli if (molecular) { int which = 0; if (!moltemplate) - which = find_special(i,j); + which = NeighborKokkosExecute::find_special(i,j); /* else if (imol >= 0) */ /* which = find_special(onemols[imol]->special[iatom], */ /* onemols[imol]->nspecial[iatom], */ @@ -558,8 +613,8 @@ void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPoli /* ---------------------------------------------------------------------- */ -template template -void NeighborKokkosExecute:: +template template +void NeighborKokkosExecute:: build_Item_Ghost(const int &i) const { /* if necessary, goto next page and add pages */ @@ -576,11 +631,10 @@ void NeighborKokkosExecute:: const X_FLOAT ztmp = x(i, 2); const int itype = type(i); - const int nstencil = neigh_list.nstencil; - const typename ArrayTypes::t_int_1d_const_um stencil - = neigh_list.d_stencil; - const typename ArrayTypes::t_int_1d_3_const_um stencilxyz - = neigh_list.d_stencilxyz; + const typename ArrayTypes::t_int_1d_const_um stencil + = d_stencil; + const typename ArrayTypes::t_int_1d_3_const_um stencilxyz + = d_stencilxyz; // 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 @@ -679,197 +733,17 @@ void NeighborKokkosExecute:: neigh_list.d_ilist(i) = i; } -template -void NeighborKokkos::full_bin_cluster_kokkos(NeighListKokkos *list) -{ - const int nall = includegroup?atom->nfirst:atom->nlocal; - list->grow(nall); +} - NeighborKokkosExecute - data(*list, - k_cutneighsq.view(), - k_bincount.view(), - k_bins.view(),nall, - atomKK->k_x.view(), - atomKK->k_type.view(), - atomKK->k_mask.view(), - atomKK->k_molecule.view(), - atomKK->k_tag.view(), - atomKK->k_special.view(), - atomKK->k_nspecial.view(), - atomKK->molecular, - nbinx,nbiny,nbinz,mbinx,mbiny,mbinz,mbinxlo,mbinylo,mbinzlo, - bininvx,bininvy,bininvz, - exclude, nex_type,maxex_type, - k_ex1_type.view(), - k_ex2_type.view(), - k_ex_type.view(), - nex_group,maxex_group, - k_ex1_group.view(), - k_ex2_group.view(), - k_ex1_bit.view(), - k_ex2_bit.view(), - nex_mol, maxex_mol, - k_ex_mol_group.view(), - k_ex_mol_bit.view(), - bboxhi,bboxlo, - domain->xperiodic,domain->yperiodic,domain->zperiodic, - domain->xprd_half,domain->yprd_half,domain->zprd_half); - - k_cutneighsq.sync(); - k_ex1_type.sync(); - k_ex2_type.sync(); - k_ex_type.sync(); - k_ex1_group.sync(); - k_ex2_group.sync(); - k_ex1_bit.sync(); - k_ex2_bit.sync(); - k_ex_mol_group.sync(); - k_ex_mol_bit.sync(); - - data.special_flag[0] = special_flag[0]; - data.special_flag[1] = special_flag[1]; - data.special_flag[2] = special_flag[2]; - data.special_flag[3] = special_flag[3]; - - atomKK->sync(Device,X_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK); - Kokkos::deep_copy(list->d_stencil,list->h_stencil); - DeviceType::fence(); - - while(data.h_resize() > 0) { - data.h_resize() = 0; - deep_copy(data.resize, data.h_resize); - - MemsetZeroFunctor f_zero; - f_zero.ptr = (void*) k_bincount.view().ptr_on_device(); - Kokkos::parallel_for(mbins, f_zero); - DeviceType::fence(); - - NeighborKokkosBinAtomsFunctor f(data); - - Kokkos::parallel_for(atom->nlocal+atom->nghost, f); - DeviceType::fence(); - - deep_copy(data.h_resize, data.resize); - if(data.h_resize()) { - - atoms_per_bin += 16; - k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin); - data.bins = k_bins.view(); - data.c_bins = data.bins; - } - } - - if(list->d_neighbors.dimension_0()d_neighbors = typename ArrayTypes::t_neighbors_2d("neighbors", nall*1.1, list->maxneighs); - list->d_numneigh = typename ArrayTypes::t_int_1d("numneigh", nall*1.1); - data.neigh_list.d_neighbors = list->d_neighbors; - data.neigh_list.d_numneigh = list->d_numneigh; - } - data.h_resize()=1; - while(data.h_resize()) { - data.h_new_maxneighs() = list->maxneighs; - data.h_resize() = 0; - - Kokkos::deep_copy(data.resize, data.h_resize); - Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs); +namespace LAMMPS_NS { +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; #ifdef KOKKOS_HAVE_CUDA - #define BINS_PER_BLOCK 2 - const int factor = atoms_per_bin<64?2:1; - Kokkos::TeamPolicy config((mbins+factor-1)/factor,atoms_per_bin*factor); -#else - const int factor = 1; +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; #endif - -if(newton_pair) { - NeighborClusterKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); -//#ifdef KOKKOS_HAVE_CUDA -// Kokkos::parallel_for(config, f); -//#else - Kokkos::parallel_for(nall, f); -//#endif -} else { - NeighborClusterKokkosBuildFunctor f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); -//#ifdef KOKKOS_HAVE_CUDA -// Kokkos::parallel_for(config, f); -//#else - Kokkos::parallel_for(nall, f); -//#endif -} - DeviceType::fence(); - deep_copy(data.h_resize, data.resize); - - if(data.h_resize()) { - deep_copy(data.h_new_maxneighs, data.new_maxneighs); - list->maxneighs = data.h_new_maxneighs() * 1.2; - list->d_neighbors = typename ArrayTypes::t_neighbors_2d("neighbors", list->d_neighbors.dimension_0(), list->maxneighs); - data.neigh_list.d_neighbors = list->d_neighbors; - data.neigh_list.maxneighs = list->maxneighs; - } - } - - list->inum = nall; - list->gnum = 0; - -} - -/* ---------------------------------------------------------------------- */ - -template template -void NeighborKokkosExecute:: - build_cluster_Item(const int &i) const -{ - /* if necessary, goto next page and add pages */ - int n = 0; - - // get subview of neighbors of i - - const AtomNeighbors neighbors_i = neigh_list.get_neighbors(i); - const X_FLOAT xtmp = x(i, 0); - const X_FLOAT ytmp = x(i, 1); - const X_FLOAT ztmp = x(i, 2); - const int itype = type(i); - - const int ibin = coord2bin(xtmp, ytmp, ztmp); - - const int nstencil = neigh_list.nstencil; - const typename ArrayTypes::t_int_1d_const_um stencil - = neigh_list.d_stencil; - - for(int k = 0; k < nstencil; k++) { - const int jbin = ibin + stencil[k]; - for(int m = 0; m < c_bincount(jbin); m++) { - const int j = c_bins(jbin,m); - bool skip = i == j; - for(int k = 0; k< (n= neigh_list.maxneighs) { - resize() = 1; - - if(n >= new_maxneighs()) new_maxneighs() = n; - } - neigh_list.d_ilist(i) = i; -} - } diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h new file mode 100644 index 0000000000..4b77175191 --- /dev/null +++ b/src/KOKKOS/npair_kokkos.h @@ -0,0 +1,424 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +typedef NPairKokkos NPairKokkosFullBinHost; +NPairStyle(full/bin/kk/host, + NPairKokkosFullBinHost, + NP_FULL | NP_BIN | NP_KOKKOS_HOST | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +typedef NPairKokkos NPairKokkosFullBinDevice; +NPairStyle(full/bin/kk/device, + NPairKokkosFullBinDevice, + NP_FULL | NP_BIN | NP_KOKKOS_DEVICE | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +typedef NPairKokkos NPairKokkosFullBinGhostHost; +NPairStyle(full/bin/ghost/kk/host, + NPairKokkosFullBinGhostHost, + NP_FULL | NP_BIN | NP_KOKKOS_HOST | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI) + +typedef NPairKokkos NPairKokkosFullBinGhostDevice; +NPairStyle(full/bin/ghost/kk/device, + NPairKokkosFullBinGhostDevice, + NP_FULL | NP_BIN | NP_KOKKOS_DEVICE | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI) + +typedef NPairKokkos NPairKokkosHalfBinHost; +NPairStyle(half/bin/kk/host, + NPairKokkosHalfBinHost, + NP_HALF | NP_BIN | NP_KOKKOS_HOST | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +typedef NPairKokkos NPairKokkosHalfBinDevice; +NPairStyle(half/bin/kk/device, + NPairKokkosHalfBinDevice, + NP_HALF | NP_BIN | NP_KOKKOS_DEVICE | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +typedef NPairKokkos NPairKokkosHalfBinGhostHost; +NPairStyle(half/bin/ghost/kk/host, + NPairKokkosHalfBinGhostHost, + NP_HALF | NP_BIN | NP_KOKKOS_HOST | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI) + +typedef NPairKokkos NPairKokkosHalfBinGhostDevice; +NPairStyle(half/bin/ghost/kk/device, + NPairKokkosHalfBinGhostDevice, + NP_HALF | NP_BIN | NP_KOKKOS_DEVICE | NP_NEWTON | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_KOKKOS_H +#define LMP_NPAIR_KOKKOS_H + +#include "npair.h" +#include "neigh_list_kokkos.h" + +namespace LAMMPS_NS { + +template +class NPairKokkos : public NPair { + public: + NPairKokkos(class LAMMPS *); + ~NPairKokkos() {} + void copy_neighbor_info(); + void copy_bin_info(); + void copy_stencil_info(); + void build(class NeighList *); + + private: + int newton_pair; + + // data from Neighbor class + + DAT::tdual_xfloat_2d k_cutneighsq; + + // exclusion data from Neighbor class + + DAT::tdual_int_1d k_ex1_type,k_ex2_type; + DAT::tdual_int_2d k_ex_type; + DAT::tdual_int_1d k_ex1_group,k_ex2_group; + DAT::tdual_int_1d k_ex1_bit,k_ex2_bit; + DAT::tdual_int_1d k_ex_mol_group; + DAT::tdual_int_1d k_ex_mol_bit; + + // data from NBin class + + int atoms_per_bin; + DAT::tdual_int_1d k_bincount; + DAT::tdual_int_2d k_bins; + + // data from NStencil class + + int nstencil; + DAT::tdual_int_1d k_stencil; // # of J neighs for each I + DAT::tdual_int_1d_3 k_stencilxyz; +}; + +template +class NeighborKokkosExecute +{ + typedef ArrayTypes AT; + + public: + NeighListKokkos neigh_list; + + // data from Neighbor class + + const typename AT::t_xfloat_2d_randomread cutneighsq; + + // exclusion data from Neighbor class + + const int exclude; + + const int nex_type; + const typename AT::t_int_1d_const ex1_type,ex2_type; + const typename AT::t_int_2d_const ex_type; + + const int nex_group; + const typename AT::t_int_1d_const ex1_group,ex2_group; + const typename AT::t_int_1d_const ex1_bit,ex2_bit; + + const int nex_mol; + const typename AT::t_int_1d_const ex_mol_group; + const typename AT::t_int_1d_const ex_mol_bit; + + // data from NBin class + + const typename AT::t_int_1d bincount; + const typename AT::t_int_1d_const c_bincount; + typename AT::t_int_2d bins; + typename AT::t_int_2d_const c_bins; + + + // data from NStencil class + + int nstencil; + typename AT::t_int_1d d_stencil; // # of J neighs for each I + typename AT::t_int_1d_3 d_stencilxyz; + + // data from Atom class + + const typename AT::t_x_array_randomread x; + const typename AT::t_int_1d_const type,mask,molecule; + const typename AT::t_tagint_1d_const tag; + const typename AT::t_tagint_2d_const special; + const typename AT::t_int_2d_const nspecial; + const int molecular; + int moltemplate; + + int special_flag[4]; + + const int nbinx,nbiny,nbinz; + const int mbinx,mbiny,mbinz; + const int mbinxlo,mbinylo,mbinzlo; + const X_FLOAT bininvx,bininvy,bininvz; + X_FLOAT bboxhi[3],bboxlo[3]; + + const int nlocal; + + typename AT::t_int_scalar resize; + typename AT::t_int_scalar new_maxneighs; + typename ArrayTypes::t_int_scalar h_resize; + typename ArrayTypes::t_int_scalar h_new_maxneighs; + + const int xperiodic, yperiodic, zperiodic; + const int xprd_half, yprd_half, zprd_half; + + NeighborKokkosExecute( + const NeighListKokkos &_neigh_list, + const typename AT::t_xfloat_2d_randomread &_cutneighsq, + const typename AT::t_int_1d &_bincount, + const typename AT::t_int_2d &_bins, + const int _nstencil, + const typename AT::t_int_1d &_d_stencil, + const typename AT::t_int_1d_3 &_d_stencilxyz, + const int _nlocal, + const typename AT::t_x_array_randomread &_x, + const typename AT::t_int_1d_const &_type, + const typename AT::t_int_1d_const &_mask, + const typename AT::t_int_1d_const &_molecule, + const typename AT::t_tagint_1d_const &_tag, + const typename AT::t_tagint_2d_const &_special, + const typename AT::t_int_2d_const &_nspecial, + const int &_molecular, + const int & _nbinx,const int & _nbiny,const int & _nbinz, + const int & _mbinx,const int & _mbiny,const int & _mbinz, + const int & _mbinxlo,const int & _mbinylo,const int & _mbinzlo, + const X_FLOAT &_bininvx,const X_FLOAT &_bininvy,const X_FLOAT &_bininvz, + const int & _exclude,const int & _nex_type, + const typename AT::t_int_1d_const & _ex1_type, + const typename AT::t_int_1d_const & _ex2_type, + const typename AT::t_int_2d_const & _ex_type, + const int & _nex_group, + const typename AT::t_int_1d_const & _ex1_group, + const typename AT::t_int_1d_const & _ex2_group, + const typename AT::t_int_1d_const & _ex1_bit, + const typename AT::t_int_1d_const & _ex2_bit, + const int & _nex_mol, + const typename AT::t_int_1d_const & _ex_mol_group, + const typename AT::t_int_1d_const & _ex_mol_bit, + const X_FLOAT *_bboxhi, const X_FLOAT* _bboxlo, + const int & _xperiodic, const int & _yperiodic, const int & _zperiodic, + const int & _xprd_half, const int & _yprd_half, const int & _zprd_half): + neigh_list(_neigh_list), cutneighsq(_cutneighsq), + bincount(_bincount),c_bincount(_bincount),bins(_bins),c_bins(_bins), + nstencil(_nstencil),d_stencil(_d_stencil),d_stencilxyz(_d_stencilxyz), + nlocal(_nlocal), + x(_x),type(_type),mask(_mask),molecule(_molecule), + tag(_tag),special(_special),nspecial(_nspecial),molecular(_molecular), + nbinx(_nbinx),nbiny(_nbiny),nbinz(_nbinz), + mbinx(_mbinx),mbiny(_mbiny),mbinz(_mbinz), + mbinxlo(_mbinxlo),mbinylo(_mbinylo),mbinzlo(_mbinzlo), + bininvx(_bininvx),bininvy(_bininvy),bininvz(_bininvz), + exclude(_exclude),nex_type(_nex_type), + ex1_type(_ex1_type),ex2_type(_ex2_type),ex_type(_ex_type), + nex_group(_nex_group), + ex1_group(_ex1_group),ex2_group(_ex2_group), + ex1_bit(_ex1_bit),ex2_bit(_ex2_bit),nex_mol(_nex_mol), + ex_mol_group(_ex_mol_group),ex_mol_bit(_ex_mol_bit), + xperiodic(_xperiodic),yperiodic(_yperiodic),zperiodic(_zperiodic), + xprd_half(_xprd_half),yprd_half(_yprd_half),zprd_half(_zprd_half) { + + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + bboxlo[0] = _bboxlo[0]; bboxlo[1] = _bboxlo[1]; bboxlo[2] = _bboxlo[2]; + bboxhi[0] = _bboxhi[0]; bboxhi[1] = _bboxhi[1]; bboxhi[2] = _bboxhi[2]; + + resize = typename AT::t_int_scalar("NeighborKokkosFunctor::resize"); +#ifndef KOKKOS_USE_CUDA_UVM + h_resize = Kokkos::create_mirror_view(resize); +#else + h_resize = resize; +#endif + h_resize() = 1; + new_maxneighs = typename AT:: + t_int_scalar("NeighborKokkosFunctor::new_maxneighs"); +#ifndef KOKKOS_USE_CUDA_UVM + h_new_maxneighs = Kokkos::create_mirror_view(new_maxneighs); +#else + h_new_maxneighs = new_maxneighs; +#endif + h_new_maxneighs() = neigh_list.maxneighs; + }; + + ~NeighborKokkosExecute() {neigh_list.clean_copy();}; + + template + KOKKOS_FUNCTION + void build_Item(const int &i) const; + + template + KOKKOS_FUNCTION + void build_Item_Ghost(const int &i) const; + +#ifdef KOKKOS_HAVE_CUDA + template + __device__ inline + void build_ItemCuda(typename Kokkos::TeamPolicy::member_type dev) const; +#endif + + KOKKOS_INLINE_FUNCTION + void binatomsItem(const int &i) const; + + KOKKOS_INLINE_FUNCTION + int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z) const + { + int ix,iy,iz; + + if (x >= bboxhi[0]) + ix = static_cast ((x-bboxhi[0])*bininvx) + nbinx; + else if (x >= bboxlo[0]) { + ix = static_cast ((x-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo[0])*bininvx) - 1; + + if (y >= bboxhi[1]) + iy = static_cast ((y-bboxhi[1])*bininvy) + nbiny; + else if (y >= bboxlo[1]) { + iy = static_cast ((y-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo[1])*bininvy) - 1; + + if (z >= bboxhi[2]) + iz = static_cast ((z-bboxhi[2])*bininvz) + nbinz; + else if (z >= bboxlo[2]) { + iz = static_cast ((z-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo[2])*bininvz) - 1; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + KOKKOS_INLINE_FUNCTION + int coord2bin(const X_FLOAT & x,const X_FLOAT & y,const X_FLOAT & z, int* i) const + { + int ix,iy,iz; + + if (x >= bboxhi[0]) + ix = static_cast ((x-bboxhi[0])*bininvx) + nbinx; + else if (x >= bboxlo[0]) { + ix = static_cast ((x-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x-bboxlo[0])*bininvx) - 1; + + if (y >= bboxhi[1]) + iy = static_cast ((y-bboxhi[1])*bininvy) + nbiny; + else if (y >= bboxlo[1]) { + iy = static_cast ((y-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((y-bboxlo[1])*bininvy) - 1; + + if (z >= bboxhi[2]) + iz = static_cast ((z-bboxhi[2])*bininvz) + nbinz; + else if (z >= bboxlo[2]) { + iz = static_cast ((z-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((z-bboxlo[2])*bininvz) - 1; + + i[0] = ix - mbinxlo; + i[1] = iy - mbinylo; + i[2] = iz - mbinzlo; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); + } + + KOKKOS_INLINE_FUNCTION + int exclusion(const int &i,const int &j, const int &itype,const int &jtype) const; + + KOKKOS_INLINE_FUNCTION + int find_special(const int &i, const int &j) const; + + KOKKOS_INLINE_FUNCTION + int minimum_image_check(double dx, double dy, double dz) const { + if (xperiodic && fabs(dx) > xprd_half) return 1; + if (yperiodic && fabs(dy) > yprd_half) return 1; + if (zperiodic && fabs(dz) > zprd_half) return 1; + return 0; + } + +}; + +template +struct NPairKokkosBuildFunctor { + typedef DeviceType device_type; + + const NeighborKokkosExecute c; + const size_t sharedsize; + + NPairKokkosBuildFunctor(const NeighborKokkosExecute &_c, + const size_t _sharedsize):c(_c), + sharedsize(_sharedsize) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int & i) const { + c.template build_Item(i); + } +#ifdef KOKKOS_HAVE_CUDA + __device__ inline + + void operator() (typename Kokkos::TeamPolicy::member_type dev) const { + c.template build_ItemCuda(dev); + } + size_t shmem_size(const int team_size) const { (void) team_size; return sharedsize; } +#endif +}; + +template +struct NPairKokkosBuildFunctor { + typedef LMPHostType device_type; + + const NeighborKokkosExecute c; + const size_t sharedsize; + + NPairKokkosBuildFunctor(const NeighborKokkosExecute &_c, + const size_t _sharedsize):c(_c), + sharedsize(_sharedsize) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int & i) const { + c.template build_Item(i); + } + + void operator() (typename Kokkos::TeamPolicy::member_type dev) const {} +}; + +template +struct NPairKokkosBuildFunctorGhost { + typedef DeviceType device_type; + + const NeighborKokkosExecute c; + const size_t sharedsize; + + NPairKokkosBuildFunctorGhost(const NeighborKokkosExecute &_c, + const size_t _sharedsize):c(_c), + sharedsize(_sharedsize) {}; + + KOKKOS_INLINE_FUNCTION + void operator() (const int & i) const { + c.template build_Item_Ghost(i); + } +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp index 4c431bb427..a176ca2be4 100644 --- a/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_cut_kokkos.cpp @@ -90,7 +90,7 @@ void PairBuckCoulCutKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -309,19 +309,12 @@ void PairBuckCoulCutKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 1; } else { error->all(FLERR,"Cannot use chosen neighbor list style with buck/coul/cut/kk"); } diff --git a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp index a7e6deb43f..413f38370d 100644 --- a/src/KOKKOS/pair_buck_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_buck_coul_long_kokkos.cpp @@ -109,7 +109,7 @@ void PairBuckCoulLongKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -458,11 +458,9 @@ void PairBuckCoulLongKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with buck/coul/long/kk"); } diff --git a/src/KOKKOS/pair_buck_kokkos.cpp b/src/KOKKOS/pair_buck_kokkos.cpp index 50d65b4b6d..02f767fa03 100644 --- a/src/KOKKOS/pair_buck_kokkos.cpp +++ b/src/KOKKOS/pair_buck_kokkos.cpp @@ -79,7 +79,7 @@ void PairBuckKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -233,19 +233,12 @@ void PairBuckKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with buck/kk"); } diff --git a/src/KOKKOS/pair_buck_kokkos.h b/src/KOKKOS/pair_buck_kokkos.h index 23ba049f9d..e95fa903fe 100644 --- a/src/KOKKOS/pair_buck_kokkos.h +++ b/src/KOKKOS/pair_buck_kokkos.h @@ -31,7 +31,7 @@ namespace LAMMPS_NS { template class PairBuckKokkos : public PairBuck { public: - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; PairBuckKokkos(class LAMMPS *); @@ -96,17 +96,14 @@ class PairBuckKokkos : public PairBuck { friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairBuckKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_fullcluster(PairBuckKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute(PairBuckKokkos*,NeighListKokkos*); friend void pair_virial_fdotr_compute(PairBuckKokkos*); }; diff --git a/src/KOKKOS/pair_coul_cut_kokkos.cpp b/src/KOKKOS/pair_coul_cut_kokkos.cpp index 7b0fbad7e5..19d4306317 100644 --- a/src/KOKKOS/pair_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_coul_cut_kokkos.cpp @@ -78,7 +78,7 @@ void PairCoulCutKokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -215,11 +215,9 @@ void PairCoulCutKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with coul/cut/kk"); } diff --git a/src/KOKKOS/pair_coul_debye_kokkos.cpp b/src/KOKKOS/pair_coul_debye_kokkos.cpp index c4b78b8910..9a6e1b8020 100644 --- a/src/KOKKOS/pair_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_coul_debye_kokkos.cpp @@ -85,7 +85,7 @@ void PairCoulDebyeKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -257,19 +257,12 @@ void PairCoulDebyeKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with coul/debye/kk"); } diff --git a/src/KOKKOS/pair_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_coul_dsf_kokkos.cpp index 503cdc280d..e689754d0a 100644 --- a/src/KOKKOS/pair_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_dsf_kokkos.cpp @@ -221,11 +221,9 @@ void PairCoulDSFKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with coul/dsf/kk"); } diff --git a/src/KOKKOS/pair_coul_long_kokkos.cpp b/src/KOKKOS/pair_coul_long_kokkos.cpp index 95b6734e94..7536549bf4 100644 --- a/src/KOKKOS/pair_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_coul_long_kokkos.cpp @@ -102,7 +102,7 @@ void PairCoulLongKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -408,11 +408,9 @@ void PairCoulLongKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with buck/coul/long/kk"); } diff --git a/src/KOKKOS/pair_coul_wolf_kokkos.cpp b/src/KOKKOS/pair_coul_wolf_kokkos.cpp index 774580c929..1785ba2731 100644 --- a/src/KOKKOS/pair_coul_wolf_kokkos.cpp +++ b/src/KOKKOS/pair_coul_wolf_kokkos.cpp @@ -222,11 +222,9 @@ void PairCoulWolfKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with coul/wolf/kk"); } diff --git a/src/KOKKOS/pair_eam_alloy_kokkos.cpp b/src/KOKKOS/pair_eam_alloy_kokkos.cpp index 151d89d2b0..f3b7c36106 100644 --- a/src/KOKKOS/pair_eam_alloy_kokkos.cpp +++ b/src/KOKKOS/pair_eam_alloy_kokkos.cpp @@ -286,11 +286,9 @@ void PairEAMAlloyKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with pair eam/kk/alloy"); } diff --git a/src/KOKKOS/pair_eam_fs_kokkos.cpp b/src/KOKKOS/pair_eam_fs_kokkos.cpp index b503d1e83a..ba450b0872 100644 --- a/src/KOKKOS/pair_eam_fs_kokkos.cpp +++ b/src/KOKKOS/pair_eam_fs_kokkos.cpp @@ -291,11 +291,9 @@ void PairEAMFSKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with pair eam/kk/fs"); } diff --git a/src/KOKKOS/pair_eam_kokkos.cpp b/src/KOKKOS/pair_eam_kokkos.cpp index d91da280ac..3d8223ed66 100644 --- a/src/KOKKOS/pair_eam_kokkos.cpp +++ b/src/KOKKOS/pair_eam_kokkos.cpp @@ -281,11 +281,9 @@ void PairEAMKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with pair eam/kk"); } diff --git a/src/KOKKOS/pair_kokkos.h b/src/KOKKOS/pair_kokkos.h index 3710c460c0..1e01b3df15 100644 --- a/src/KOKKOS/pair_kokkos.h +++ b/src/KOKKOS/pair_kokkos.h @@ -333,145 +333,6 @@ struct PairComputeFunctor { } }; -template -struct PairComputeFunctor { - typedef typename PairStyle::device_type device_type ; - typedef EV_FLOAT value_type; - - PairStyle c; - NeighListKokkos list; - - PairComputeFunctor(PairStyle* c_ptr, - NeighListKokkos* list_ptr): - c(*c_ptr),list(*list_ptr) {}; - ~PairComputeFunctor() {c.cleanup_copy();list.clean_copy();}; - - KOKKOS_INLINE_FUNCTION int sbmask(const int& j) const { - return j >> SBBITS & 3; - } - - template - KOKKOS_FUNCTION - EV_FLOAT compute_item(const typename Kokkos::TeamPolicy::member_type& dev, - const NeighListKokkos &list, const NoCoulTag& ) const { - EV_FLOAT ev; - int i = dev.league_rank()*dev.team_size() + dev.team_rank(); - - const X_FLOAT xtmp = c.c_x(i,0); - const X_FLOAT ytmp = c.c_x(i,1); - const X_FLOAT ztmp = c.c_x(i,2); - int itype = c.type(i); - - const AtomNeighborsConst neighbors_i = list.get_neighbors_const(i); - const int jnum = list.d_numneigh[i]; - - F_FLOAT3 ftmp; - - for (int jj = 0; jj < jnum; jj++) { - int jjj = neighbors_i(jj); - - Kokkos::parallel_reduce(Kokkos::ThreadVectorRange(dev,NeighClusterSize),[&] (const int& k, F_FLOAT3& fftmp) { - const F_FLOAT factor_lj = c.special_lj[sbmask(jjj+k)]; - const int j = (jjj + k)&NEIGHMASK; - if((j==i)||(j>=c.nall)) return; - const X_FLOAT delx = xtmp - c.c_x(j,0); - const X_FLOAT dely = ytmp - c.c_x(j,1); - const X_FLOAT delz = ztmp - c.c_x(j,2); - const int jtype = c.type(j); - const F_FLOAT rsq = (delx*delx + dely*dely + delz*delz); - - if(rsq < (STACKPARAMS?c.m_cutsq[itype][jtype]:c.d_cutsq(itype,jtype))) { - - const F_FLOAT fpair = factor_lj*c.template compute_fpair(rsq,i,j,itype,jtype); - fftmp.x += delx*fpair; - fftmp.y += dely*fpair; - fftmp.z += delz*fpair; - - if (EVFLAG) { - F_FLOAT evdwl = 0.0; - if (c.eflag) { - evdwl = 0.5* - factor_lj * c.template compute_evdwl(rsq,i,j,itype,jtype); - ev.evdwl += evdwl; - } - - if (c.vflag_either || c.eflag_atom) ev_tally(ev,i,j,evdwl,fpair,delx,dely,delz); - } - } - },ftmp); - } - - Kokkos::single(Kokkos::PerThread(dev), [&]() { - c.f(i,0) += ftmp.x; - c.f(i,1) += ftmp.y; - c.f(i,2) += ftmp.z; - }); - - return ev; - } - - KOKKOS_INLINE_FUNCTION - void ev_tally(EV_FLOAT &ev, const int &i, const int &j, - const F_FLOAT &epair, const F_FLOAT &fpair, const F_FLOAT &delx, - const F_FLOAT &dely, const F_FLOAT &delz) const - { - const int EFLAG = c.eflag; - const int NEWTON_PAIR = c.newton_pair; - const int VFLAG = c.vflag_either; - - if (EFLAG) { - if (c.eflag_atom) { - const E_FLOAT epairhalf = 0.5 * epair; - if (NEWTON_PAIR || i < c.nlocal) c.d_eatom[i] += epairhalf; - if (NEWTON_PAIR || j < c.nlocal) c.d_eatom[j] += epairhalf; - } - } - - if (VFLAG) { - const E_FLOAT v0 = delx*delx*fpair; - const E_FLOAT v1 = dely*dely*fpair; - const E_FLOAT v2 = delz*delz*fpair; - const E_FLOAT v3 = delx*dely*fpair; - const E_FLOAT v4 = delx*delz*fpair; - const E_FLOAT v5 = dely*delz*fpair; - - if (c.vflag_global) { - ev.v[0] += 0.5*v0; - ev.v[1] += 0.5*v1; - ev.v[2] += 0.5*v2; - ev.v[3] += 0.5*v3; - ev.v[4] += 0.5*v4; - ev.v[5] += 0.5*v5; - } - - if (c.vflag_atom) { - if (i < c.nlocal) { - c.d_vatom(i,0) += 0.5*v0; - c.d_vatom(i,1) += 0.5*v1; - c.d_vatom(i,2) += 0.5*v2; - c.d_vatom(i,3) += 0.5*v3; - c.d_vatom(i,4) += 0.5*v4; - c.d_vatom(i,5) += 0.5*v5; - } - } - } - } - - KOKKOS_INLINE_FUNCTION - void operator()(const typename Kokkos::TeamPolicy::member_type& dev) const { - if (c.newton_pair) compute_item<0,1>(dev,list,typename DoCoul::type()); - else compute_item<0,0>(dev,list,typename DoCoul::type()); - } - - KOKKOS_INLINE_FUNCTION - void operator()(const typename Kokkos::TeamPolicy::member_type& dev, value_type &energy_virial) const { - if (c.newton_pair) - energy_virial += compute_item<1,1>(dev,list,typename DoCoul::type()); - else - energy_virial += compute_item<1,0>(dev,list,typename DoCoul::type()); - } -}; - template struct PairComputeFunctor { typedef typename PairStyle::device_type device_type ; @@ -607,8 +468,8 @@ struct PairComputeFunctor { // The enable_if clause will invalidate the last parameter of the function, so that // a match is only achieved, if PairStyle supports the specific neighborlist variant. // This uses the fact that failure to match template parameters is not an error. -// By having the enable_if with a ! and without it, exactly one of the two versions of the functions -// pair_compute_neighlist and pair_compute_fullcluster will match - either the dummy version +// By having the enable_if with a ! and without it, exactly one of the functions +// pair_compute_neighlist will match - either the dummy version // or the real one further below. template EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable_if*>::type list) { @@ -619,15 +480,6 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable return ev; } -template -EV_FLOAT pair_compute_fullcluster (PairStyle* fpair, typename Kokkos::Impl::enable_if*>::type list) { - EV_FLOAT ev; - (void) fpair; - (void) list; - printf("ERROR: calling pair_compute with invalid neighbor list style: requested %i available %i \n",FULLCLUSTER,PairStyle::EnabledNeighFlags); - return ev; -} - // Submit ParallelFor for NEIGHFLAG=HALF,HALFTHREAD,FULL,N2 template EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable_if<(NEIGHFLAG&PairStyle::EnabledNeighFlags) != 0, NeighListKokkos*>::type list) { @@ -644,41 +496,6 @@ EV_FLOAT pair_compute_neighlist (PairStyle* fpair, typename Kokkos::Impl::enable return ev; } -// Submit ParallelFor for NEIGHFLAG=FULLCLUSTER -template -EV_FLOAT pair_compute_fullcluster (PairStyle* fpair, typename Kokkos::Impl::enable_if<(FULLCLUSTER&PairStyle::EnabledNeighFlags) != 0, NeighListKokkos*>::type list) { - EV_FLOAT ev; - if(fpair->atom->ntypes > MAX_TYPES_STACKPARAMS) { - typedef PairComputeFunctor - f_type; - f_type ff(fpair, list); - #ifdef KOKKOS_HAVE_CUDA - const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; - #else - const int teamsize = 1; - #endif - const int nteams = (list->inum*+teamsize-1)/teamsize; - Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(config,ff,ev); - else Kokkos::parallel_for(config,ff); - } else { - typedef PairComputeFunctor - f_type; - f_type ff(fpair, list); - #ifdef KOKKOS_HAVE_CUDA - const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; - #else - const int teamsize = 1; - #endif - const int nteams = (list->inum*+teamsize-1)/teamsize; - Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); - if (fpair->eflag || fpair->vflag) Kokkos::parallel_reduce(config,ff,ev); - else Kokkos::parallel_for(config,ff); - } - return ev; -} - - template EV_FLOAT pair_compute (PairStyle* fpair, NeighListKokkos* list) { EV_FLOAT ev; @@ -690,8 +507,6 @@ EV_FLOAT pair_compute (PairStyle* fpair, NeighListKokkos (fpair,list); } else if (fpair->neighflag == N2) { ev = pair_compute_neighlist (fpair,list); - } else if (fpair->neighflag == FULLCLUSTER) { - ev = pair_compute_fullcluster (fpair,list); } return ev; } diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp index d438e64e7d..914711a8e5 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_implicit_kokkos.cpp @@ -110,7 +110,7 @@ void PairLJCharmmCoulCharmmImplicitKokkos::compute(int eflag_in, int eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -455,11 +455,9 @@ void PairLJCharmmCoulCharmmImplicitKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/charmm/coul/charmm/implicit/kk"); } diff --git a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp index 4e125235f4..4af6a896d0 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_charmm_kokkos.cpp @@ -110,7 +110,7 @@ void PairLJCharmmCoulCharmmKokkos::compute(int eflag_in, int vflag_i eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -456,11 +456,9 @@ void PairLJCharmmCoulCharmmKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/charmm/coul/charmm/kk"); } diff --git a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp index 3b2b13f40b..5efba2742d 100644 --- a/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_charmm_coul_long_kokkos.cpp @@ -110,7 +110,7 @@ void PairLJCharmmCoulLongKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -486,11 +486,9 @@ void PairLJCharmmCoulLongKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/charmm/coul/long/kk"); } diff --git a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp index 87cd1cb7e1..96507a599e 100644 --- a/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp @@ -87,7 +87,7 @@ void PairLJClass2CoulCutKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -289,19 +289,12 @@ void PairLJClass2CoulCutKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/class2/coul/cut/kk"); } diff --git a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp index 297a764dda..2d1abc9cd3 100644 --- a/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_coul_long_kokkos.cpp @@ -95,7 +95,7 @@ void PairLJClass2CoulLongKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -445,11 +445,9 @@ void PairLJClass2CoulLongKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/class2/coul/long/kk"); } diff --git a/src/KOKKOS/pair_lj_class2_kokkos.cpp b/src/KOKKOS/pair_lj_class2_kokkos.cpp index a263e81e0e..b5c4c19b8e 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.cpp +++ b/src/KOKKOS/pair_lj_class2_kokkos.cpp @@ -87,7 +87,7 @@ void PairLJClass2Kokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -227,19 +227,12 @@ void PairLJClass2Kokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/class2/kk"); } diff --git a/src/KOKKOS/pair_lj_class2_kokkos.h b/src/KOKKOS/pair_lj_class2_kokkos.h index 8dcabe5b0c..e8ac07da80 100644 --- a/src/KOKKOS/pair_lj_class2_kokkos.h +++ b/src/KOKKOS/pair_lj_class2_kokkos.h @@ -31,7 +31,7 @@ namespace LAMMPS_NS { template class PairLJClass2Kokkos : public PairLJClass2 { public: - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; PairLJClass2Kokkos(class LAMMPS *); @@ -99,17 +99,14 @@ class PairLJClass2Kokkos : public PairLJClass2 { friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend EV_FLOAT pair_compute_neighlist(PairLJClass2Kokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJClass2Kokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJClass2Kokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJClass2Kokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_fullcluster(PairLJClass2Kokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute(PairLJClass2Kokkos*,NeighListKokkos*); friend void pair_virial_fdotr_compute(PairLJClass2Kokkos*); }; diff --git a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp index b6071880cf..e68ec5579c 100644 --- a/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp @@ -87,7 +87,7 @@ void PairLJCutCoulCutKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -280,19 +280,12 @@ void PairLJCutCoulCutKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/coul/cut/kk"); } diff --git a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp index 1da18f0afe..f4011b6f5c 100644 --- a/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp @@ -91,7 +91,7 @@ void PairLJCutCoulDebyeKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -310,19 +310,12 @@ void PairLJCutCoulDebyeKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/coul/debye/kk"); } diff --git a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp index 46cb0a96dc..13c930a15b 100644 --- a/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp @@ -99,7 +99,7 @@ void PairLJCutCoulDSFKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -301,19 +301,12 @@ void PairLJCutCoulDSFKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/coul/cut/kk"); } diff --git a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp index 2a1a124460..42319cfa99 100644 --- a/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp @@ -99,7 +99,7 @@ void PairLJCutCoulLongKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -464,11 +464,9 @@ void PairLJCutCoulLongKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/coul/long/kk"); } diff --git a/src/KOKKOS/pair_lj_cut_kokkos.cpp b/src/KOKKOS/pair_lj_cut_kokkos.cpp index 2ad7f2d014..5f2805622a 100644 --- a/src/KOKKOS/pair_lj_cut_kokkos.cpp +++ b/src/KOKKOS/pair_lj_cut_kokkos.cpp @@ -87,7 +87,7 @@ void PairLJCutKokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -245,19 +245,12 @@ void PairLJCutKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/kk"); } diff --git a/src/KOKKOS/pair_lj_cut_kokkos.h b/src/KOKKOS/pair_lj_cut_kokkos.h index 16efd3d2ef..b779874fe8 100644 --- a/src/KOKKOS/pair_lj_cut_kokkos.h +++ b/src/KOKKOS/pair_lj_cut_kokkos.h @@ -31,7 +31,7 @@ namespace LAMMPS_NS { template class PairLJCutKokkos : public PairLJCut { public: - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; PairLJCutKokkos(class LAMMPS *); @@ -99,17 +99,14 @@ class PairLJCutKokkos : public PairLJCut { friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend EV_FLOAT pair_compute_neighlist(PairLJCutKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJCutKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJCutKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJCutKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_fullcluster(PairLJCutKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute(PairLJCutKokkos*,NeighListKokkos*); friend void pair_virial_fdotr_compute(PairLJCutKokkos*); }; diff --git a/src/KOKKOS/pair_lj_expand_kokkos.cpp b/src/KOKKOS/pair_lj_expand_kokkos.cpp index 3e1d185d2f..3ed03f0d0b 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.cpp +++ b/src/KOKKOS/pair_lj_expand_kokkos.cpp @@ -86,7 +86,7 @@ void PairLJExpandKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -230,19 +230,12 @@ void PairLJExpandKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/expand/kk"); } diff --git a/src/KOKKOS/pair_lj_expand_kokkos.h b/src/KOKKOS/pair_lj_expand_kokkos.h index 172ccaae73..339950a6b2 100644 --- a/src/KOKKOS/pair_lj_expand_kokkos.h +++ b/src/KOKKOS/pair_lj_expand_kokkos.h @@ -31,7 +31,7 @@ namespace LAMMPS_NS { template class PairLJExpandKokkos : public PairLJExpand { public: - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; PairLJExpandKokkos(class LAMMPS *); @@ -100,17 +100,14 @@ class PairLJExpandKokkos : public PairLJExpand { friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend EV_FLOAT pair_compute_neighlist(PairLJExpandKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJExpandKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJExpandKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJExpandKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_fullcluster(PairLJExpandKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute(PairLJExpandKokkos*,NeighListKokkos*); friend void pair_virial_fdotr_compute(PairLJExpandKokkos*); }; diff --git a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp index c764af303f..943cf988c9 100644 --- a/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_coul_gromacs_kokkos.cpp @@ -101,7 +101,7 @@ void PairLJGromacsCoulGromacsKokkos::compute(int eflag_in, int vflag eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -439,11 +439,9 @@ void PairLJGromacsCoulGromacsKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/gromacs/coul/gromacs/kk"); } diff --git a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp index 2f144599ac..bb4dcb39bf 100644 --- a/src/KOKKOS/pair_lj_gromacs_kokkos.cpp +++ b/src/KOKKOS/pair_lj_gromacs_kokkos.cpp @@ -98,7 +98,7 @@ void PairLJGromacsKokkos::compute(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -277,11 +277,9 @@ void PairLJGromacsKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/gromacs/kk"); } diff --git a/src/KOKKOS/pair_lj_sdk_kokkos.cpp b/src/KOKKOS/pair_lj_sdk_kokkos.cpp index 74183dff0b..46715e6fa3 100644 --- a/src/KOKKOS/pair_lj_sdk_kokkos.cpp +++ b/src/KOKKOS/pair_lj_sdk_kokkos.cpp @@ -86,7 +86,7 @@ void PairLJSDKKokkos::compute(int eflag_in, int vflag_in) vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -258,19 +258,12 @@ void PairLJSDKKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/sdk/kk"); } diff --git a/src/KOKKOS/pair_lj_sdk_kokkos.h b/src/KOKKOS/pair_lj_sdk_kokkos.h index 090b9aa562..03ca361c1b 100644 --- a/src/KOKKOS/pair_lj_sdk_kokkos.h +++ b/src/KOKKOS/pair_lj_sdk_kokkos.h @@ -31,7 +31,7 @@ namespace LAMMPS_NS { template class PairLJSDKKokkos : public PairLJSDK { public: - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; PairLJSDKKokkos(class LAMMPS *); @@ -97,17 +97,14 @@ class PairLJSDKKokkos : public PairLJSDK { friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; friend class PairComputeFunctor; - friend class PairComputeFunctor; friend EV_FLOAT pair_compute_neighlist(PairLJSDKKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJSDKKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJSDKKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute_neighlist(PairLJSDKKokkos*,NeighListKokkos*); - friend EV_FLOAT pair_compute_fullcluster(PairLJSDKKokkos*,NeighListKokkos*); friend EV_FLOAT pair_compute(PairLJSDKKokkos*,NeighListKokkos*); friend void pair_virial_fdotr_compute(PairLJSDKKokkos*); }; diff --git a/src/KOKKOS/pair_reax_c_kokkos.cpp b/src/KOKKOS/pair_reax_c_kokkos.cpp index 894c3ab53c..0fbf579a92 100644 --- a/src/KOKKOS/pair_reax_c_kokkos.cpp +++ b/src/KOKKOS/pair_reax_c_kokkos.cpp @@ -146,12 +146,10 @@ void PairReaxCKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; neighbor->requests[irequest]->ghost = 1; } else { error->all(FLERR,"Cannot use chosen neighbor list style with reax/c/kk"); diff --git a/src/KOKKOS/pair_sw_kokkos.cpp b/src/KOKKOS/pair_sw_kokkos.cpp index d2cda316be..8d0f2fcfc3 100644 --- a/src/KOKKOS/pair_sw_kokkos.cpp +++ b/src/KOKKOS/pair_sw_kokkos.cpp @@ -601,7 +601,6 @@ void PairSWKokkos::init_style() if (neighflag == FULL || neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; if (neighflag == FULL) neighbor->requests[irequest]->ghost = 1; else diff --git a/src/KOKKOS/pair_table_kokkos.cpp b/src/KOKKOS/pair_table_kokkos.cpp index 278c5b0a2f..5230d1a91f 100644 --- a/src/KOKKOS/pair_table_kokkos.cpp +++ b/src/KOKKOS/pair_table_kokkos.cpp @@ -96,7 +96,7 @@ void PairTableKokkos::compute_style(int eflag_in, int vflag_in) eflag = eflag_in; vflag = vflag_in; - if (neighflag == FULL || neighflag == FULLCLUSTER) no_virial_fdotr_compute = 1; + if (neighflag == FULL) no_virial_fdotr_compute = 1; if (eflag || vflag) ev_setup(eflag,vflag); else evflag = vflag_fdotr = 0; @@ -142,19 +142,6 @@ void PairTableKokkos::compute_style(int eflag_in, int vflag_in) f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); - } else if (neighflag == FULLCLUSTER) { - typedef PairComputeFunctor,FULLCLUSTER,false,S_TableCompute > - f_type; - f_type f(this,(NeighListKokkos*) list); - #ifdef KOKKOS_HAVE_CUDA - const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; - #else - const int teamsize = 1; - #endif - const int nteams = (list->inum*+teamsize-1)/teamsize; - Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); - if (eflag || vflag) Kokkos::parallel_reduce(config,f,ev); - else Kokkos::parallel_for(config,f); } } else { if (neighflag == FULL) { @@ -177,19 +164,6 @@ void PairTableKokkos::compute_style(int eflag_in, int vflag_in) f(this,(NeighListKokkos*) list); if (eflag || vflag) Kokkos::parallel_reduce(nlocal,f,ev); else Kokkos::parallel_for(nlocal,f); - } else if (neighflag == FULLCLUSTER) { - typedef PairComputeFunctor,FULLCLUSTER,true,S_TableCompute > - f_type; - f_type f(this,(NeighListKokkos*) list); - #ifdef KOKKOS_HAVE_CUDA - const int teamsize = Kokkos::Impl::is_same::value ? 32 : 1; - #else - const int teamsize = 1; - #endif - const int nteams = (list->inum*+teamsize-1)/teamsize; - Kokkos::TeamPolicy config(nteams,teamsize,NeighClusterSize); - if (eflag || vflag) Kokkos::parallel_reduce(config,f,ev); - else Kokkos::parallel_for(config,f); } } @@ -1261,19 +1235,12 @@ void PairTableKokkos::init_style() if (neighflag == FULL) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 1; - neighbor->requests[irequest]->full_cluster = 0; } else if (neighflag == N2) { neighbor->requests[irequest]->full = 0; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; - } else if (neighflag == FULLCLUSTER) { - neighbor->requests[irequest]->full_cluster = 1; - neighbor->requests[irequest]->full = 1; - neighbor->requests[irequest]->half = 0; } else { error->all(FLERR,"Cannot use chosen neighbor list style with lj/cut/kk"); } diff --git a/src/KOKKOS/pair_table_kokkos.h b/src/KOKKOS/pair_table_kokkos.h index 09e64804b4..4d3a9ec106 100644 --- a/src/KOKKOS/pair_table_kokkos.h +++ b/src/KOKKOS/pair_table_kokkos.h @@ -41,7 +41,7 @@ template class PairTableKokkos : public Pair { public: - enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2|FULLCLUSTER}; + enum {EnabledNeighFlags=FULL|HALFTHREAD|HALF|N2}; enum {COUL_FLAG=0}; typedef DeviceType device_type; @@ -170,45 +170,37 @@ class PairTableKokkos : public Pair { friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; friend class PairComputeFunctor >; - friend class PairComputeFunctor >; friend void pair_virial_fdotr_compute(PairTableKokkos*); }; diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 2908622e87..40e54df33b 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -103,7 +103,6 @@ void PairTersoffKokkos::init_style() //if (neighflag == FULL || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; if (neighflag == FULL) neighbor->requests[irequest]->ghost = 1; else diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 3406c607f3..dd6adb128c 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -102,7 +102,6 @@ void PairTersoffMODKokkos::init_style() if (neighflag == FULL || neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; if (neighflag == FULL) neighbor->requests[irequest]->ghost = 1; else diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index 07341911bd..40145dbec0 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -113,7 +113,6 @@ void PairTersoffZBLKokkos::init_style() if (neighflag == FULL || neighflag == HALF || neighflag == HALFTHREAD) { neighbor->requests[irequest]->full = 1; neighbor->requests[irequest]->half = 0; - neighbor->requests[irequest]->full_cluster = 0; if (neighflag == FULL) neighbor->requests[irequest]->ghost = 1; else diff --git a/src/Make.sh b/src/Make.sh index fbed1a8bcd..83880780ec 100644 --- a/src/Make.sh +++ b/src/Make.sh @@ -59,8 +59,9 @@ style () { # called by "make machine" # col 1 = string to search for # col 2 = search in *.h files starting with this name -# col 3 = prefix of style file -# col 4 +# col 3 = name of style file +# col 4 = file that includes the style file +# col 5 = optional 2nd file that includes the style file if (test $1 = "style") then @@ -69,7 +70,7 @@ if (test $1 = "style") then style BODY_CLASS body_ body atom_vec_body style BOND_CLASS bond_ bond force style COMMAND_CLASS "" command input - style COMPUTE_CLASS compute_ compute modify modify_cuda + style COMPUTE_CLASS compute_ compute modify style DIHEDRAL_CLASS dihedral_ dihedral force style DUMP_CLASS dump_ dump output write_dump style FIX_CLASS fix_ fix modify @@ -77,6 +78,10 @@ if (test $1 = "style") then style INTEGRATE_CLASS "" integrate update style KSPACE_CLASS "" kspace force style MINIMIZE_CLASS min_ minimize update + style NBIN_CLASS nbin_ nbin neighbor + style NPAIR_CLASS npair_ npair neighbor + style NSTENCIL_CLASS nstencil_ nstencil neighbor + style NTOPO_CLASS ntopo_ ntopo neighbor style PAIR_CLASS pair_ pair force style READER_CLASS reader_ reader read_dump style REGION_CLASS region_ region domain diff --git a/src/Purge.list b/src/Purge.list index 995385dfd4..554c5df824 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -13,6 +13,40 @@ style_kspace.h style_minimize.h style_pair.h style_region.h +style_neigh_bin.h +style_neigh_pair.h +style_neigh_stencil.h +# deleted on ## XXX 2016 +accelerator_intel.h +neigh_bond.cpp +neigh_bond.h +neigh_derive.cpp +neigh_derive.h +neigh_full.cpp +neigh_full.h +neigh_gran.cpp +neigh_gran.h +neigh_half_bin.cpp +neigh_half_bin.h +neigh_half_multi.cpp +neigh_half_multi.h +neigh_half_nsq.cpp +neigh_half_nsq.h +neigh_respa.cpp +neigh_respa.h +neigh_shardlow.cpp +neigh_shardlow.h +neigh_stencil.cpp +neigh_half_bin_intel.cpp +neigh_full_kokkos.h +neighbor_omp.h +neigh_derive_omp.cpp +neigh_full_omp.cpp +neigh_gran_omp.cpp +neigh_half_bin_omp.cpp +neigh_half_multi_omp.cpp +neigh_half_nsq_omp.cpp +neigh_respa_omp.cpp # deleted on 20 Sep 2016 fix_ti_rs.cpp fix_ti_rs.h diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index e16c81c5bb..28c5382237 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -47,6 +47,7 @@ #include "comm.h" #include "neighbor.h" #include "neigh_list.h" +#include "neigh_request.h" #include "random_mars.h" #include "memory.h" #include "domain.h" @@ -139,6 +140,23 @@ int FixShardlow::setmask() /* ---------------------------------------------------------------------- */ +void FixShardlow::init() +{ + int irequest = neighbor->request(this,instance_me); + neighbor->requests[irequest]->pair = 0; + neighbor->requests[irequest]->fix = 1; + neighbor->requests[irequest]->ssa = 1; +} + +/* ---------------------------------------------------------------------- */ + +void FixShardlow::init_list(int id, NeighList *ptr) +{ + list = ptr; +} + +/* ---------------------------------------------------------------------- */ + void FixShardlow::pre_exchange() { memset(atom->ssaAIR, 0, sizeof(int)*atom->nlocal); @@ -217,7 +235,6 @@ void FixShardlow::ssa_update( int newton_pair = force->newton_pair; double randPair; - int *ssaAIR = atom->ssaAIR; double *uCond = atom->uCond; double *uMech = atom->uMech; double *dpdTheta = atom->dpdTheta; @@ -411,7 +428,6 @@ void FixShardlow::initial_integrate(int vflag) int nghost = atom->nghost; int airnum; - class NeighList *list; // points to list in pairDPD or pairDPDE class RanMars *pRNG; // NOTE: this logic is specific to orthogonal boxes, not triclinic @@ -432,12 +448,10 @@ void FixShardlow::initial_integrate(int vflag) // Allocate memory for v_t0 to hold the initial velocities for the ghosts v_t0 = (double (*)[3]) memory->smalloc(sizeof(double)*3*nghost, "FixShardlow:v_t0"); - // Define pointers to access the neighbor list and RNG + // Define pointers to access the RNG if(pairDPDE){ - list = pairDPDE->list; pRNG = pairDPDE->random; } else { - list = pairDPD->list; pRNG = pairDPD->random; } inum = list->inum; diff --git a/src/USER-DPD/fix_shardlow.h b/src/USER-DPD/fix_shardlow.h index ede0ef4e0b..45a7b030b9 100644 --- a/src/USER-DPD/fix_shardlow.h +++ b/src/USER-DPD/fix_shardlow.h @@ -26,9 +26,13 @@ namespace LAMMPS_NS { class FixShardlow : public Fix { public: + class NeighList *list; // The SSA specific neighbor list + FixShardlow(class LAMMPS *, int, char **); ~FixShardlow(); int setmask(); + virtual void init(); + virtual void init_list(int, class NeighList *); virtual void setup(int); virtual void initial_integrate(int); void setup_pre_exchange(); diff --git a/src/USER-DPD/nbin_ssa.cpp b/src/USER-DPD/nbin_ssa.cpp new file mode 100644 index 0000000000..d55acb6040 --- /dev/null +++ b/src/USER-DPD/nbin_ssa.cpp @@ -0,0 +1,129 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos (ARL) and Timothy I. Mattox (Engility Corporation) +------------------------------------------------------------------------- */ + +#include "nbin_ssa.h" +#include "atom.h" +#include "group.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NBinSSA::NBinSSA(LAMMPS *lmp) : NBinStandard(lmp) +{ + maxbin_ssa = 0; + bins_ssa = NULL; + maxhead_ssa = 0; + binhead_ssa = NULL; + gbinhead_ssa = NULL; +} + +NBinSSA::~NBinSSA() +{ + memory->destroy(bins_ssa); + memory->destroy(binhead_ssa); + memory->destroy(gbinhead_ssa); +} + +/* ---------------------------------------------------------------------- + bin owned and ghost atoms for the Shardlow Splitting Algorithm (SSA) + local atoms are in distinct bins (binhead_ssa) from the ghosts + ghost atoms are in distinct bins (gbinhead_ssa) from the locals + ghosts which are not in an Active Interaction Region (AIR) are skipped +------------------------------------------------------------------------- */ + +void NBinSSA::bin_atoms() +{ + int i,ibin; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) nlocal = atom->nfirst; + double **x = atom->x; + int *mask = atom->mask; + int *ssaAIR = atom->ssaAIR; + + for (i = 0; i < mbins; i++) { + gbinhead_ssa[i] = -1; + binhead_ssa[i] = -1; + } + + // bin in reverse order so linked list will be in forward order + + if (includegroup) { + int bitmask = group->bitmask[includegroup]; + int nowned = atom->nlocal; // NOTE: nlocal was set to atom->nfirst above + for (i = nall-1; i >= nowned; i--) { + if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR + if (mask[i] & bitmask) { + ibin = coord2bin(x[i]); + bins_ssa[i] = gbinhead_ssa[ibin]; + gbinhead_ssa[ibin] = i; + } + } + } else { + for (i = nall-1; i >= nlocal; i--) { + if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR + ibin = coord2bin(x[i]); + bins_ssa[i] = gbinhead_ssa[ibin]; + gbinhead_ssa[ibin] = i; + } + } + for (i = nlocal-1; i >= 0; i--) { + ibin = coord2bin(x[i]); + bins_ssa[i] = binhead_ssa[ibin]; + binhead_ssa[ibin] = i; + } +} + +/* ---------------------------------------------------------------------- */ + +void NBinSSA::bin_atoms_setup(int nall) +{ + NBinStandard::bin_atoms_setup(nall); // Setup the parent class's data too + + if (mbins > maxhead_ssa) { + maxhead_ssa = mbins; + memory->destroy(gbinhead_ssa); + memory->destroy(binhead_ssa); + memory->create(binhead_ssa,maxhead_ssa,"binhead_ssa"); + memory->create(gbinhead_ssa,maxhead_ssa,"gbinhead_ssa"); + } + + if (nall > maxbin_ssa) { + maxbin_ssa = nall; + memory->destroy(bins_ssa); + memory->create(bins_ssa,maxbin_ssa,"bins_ssa"); + } +} + +/* ---------------------------------------------------------------------- */ + +bigint NBinSSA::memory_usage() +{ + bigint bytes = NBinStandard::memory_usage(); // Count the parent's usage too + + if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa); + if (maxhead_ssa) { + bytes += memory->usage(binhead_ssa,maxhead_ssa); + bytes += memory->usage(gbinhead_ssa,maxhead_ssa); + } + return bytes; +} + diff --git a/src/USER-DPD/nbin_ssa.h b/src/USER-DPD/nbin_ssa.h new file mode 100644 index 0000000000..f0699b3a7a --- /dev/null +++ b/src/USER-DPD/nbin_ssa.h @@ -0,0 +1,54 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NBIN_CLASS + +NBinStyle(ssa, + NBinSSA, + NB_SSA) + +#else + +#ifndef LMP_NBIN_SSA_H +#define LMP_NBIN_SSA_H + +#include "nbin_standard.h" + +namespace LAMMPS_NS { + +class NBinSSA : public NBinStandard { + public: + + int *bins_ssa; // index of next atom in each bin + int maxbin_ssa; // size of bins_ssa array + int *binhead_ssa; // index of 1st local atom in each bin + int *gbinhead_ssa; // index of 1st ghost atom in each bin + int maxhead_ssa; // size of binhead_ssa and gbinhead_ssa arrays + + NBinSSA(class LAMMPS *); + ~NBinSSA(); + + void bin_atoms_setup(int); + void bin_atoms(); + + bigint memory_usage(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp new file mode 100644 index 0000000000..fa000233a9 --- /dev/null +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -0,0 +1,260 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos and Timothy I. Mattox (Engility Corporation) +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newton_ssa.h" +#include "neighbor.h" +#include "nstencil_ssa.h" +#include "nbin_ssa.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "group.h" +#include "memory.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +// allocate space for static class variable +// prototype for non-class function + +static int *ssaAIRptr; +static int cmp_ssaAIR(const void *, const void *); + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction with full Newton's 3rd law + for use by Shardlow Spliting Algorithm + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +void NPairHalfBinNewtonSSA::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) nlocal = atom->nfirst; + int *ssaAIR = atom->ssaAIR; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + int molecular = atom->molecular; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + NStencilSSA *ns_ssa = dynamic_cast(ns); + if (!ns_ssa) error->one(FLERR, "NStencil wasn't a NStencilSSA object"); + int nstencil_half = ns_ssa->nstencil_half; + int nstencil_full = ns_ssa->nstencil; + + NBinSSA *nb_ssa = dynamic_cast(nb); + if (!nb_ssa) error->one(FLERR, "NBin wasn't a NBinSSA object"); + int *bins_ssa = nb_ssa->bins_ssa; + int *binhead_ssa = nb_ssa->binhead_ssa; + int *gbinhead_ssa = nb_ssa->gbinhead_ssa; + + int inum = 0; + + ipage->reset(); + + // loop over owned atoms, storing half of the neighbors + + for (i = 0; i < nlocal; i++) { + int AIRct[8] = { 0 }; + 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 local atoms in i's bin + // just store them, since j is beyond i in linked list + + for (j = bins_ssa[i]; j >= 0; j = bins_ssa[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) { + 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; + } + } + + ibin = coord2bin(x[i]); + + // loop over all local atoms in other bins in "half" stencil + + for (k = 0; k < nstencil_half; k++) { + for (j = binhead_ssa[ibin+stencil[k]]; j >= 0; + j = bins_ssa[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) { + 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; + } + } + } + AIRct[0] = n; + + // loop over AIR ghost atoms in all bins in "full" stencil + // Note: the non-AIR ghost atoms have already been filtered out + // That is a significant time savings because of the "full" stencil + // Note2: only non-pure locals can have ghosts as neighbors + + if (ssaAIR[i] == 1) for (k = 0; k < nstencil_full; k++) { + for (j = gbinhead_ssa[ibin+stencil[k]]; j >= 0; + j = bins_ssa[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) { + 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; + ++(AIRct[ssaAIR[j] - 1]); + } else if (domain->minimum_image_check(delx,dely,delz)) { + neighptr[n++] = j; + ++(AIRct[ssaAIR[j] - 1]); + } else if (which > 0) { + neighptr[n++] = j ^ (which << SBBITS); + ++(AIRct[ssaAIR[j] - 1]); + } + } else { + neighptr[n++] = j; + ++(AIRct[ssaAIR[j] - 1]); + } + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + // sort the ghosts in the neighbor list by their ssaAIR number + + ssaAIRptr = atom->ssaAIR; + qsort(&(neighptr[AIRct[0]]), n - AIRct[0], sizeof(int), cmp_ssaAIR); + + // do a prefix sum on the counts to turn them into indexes + + list->ndxAIR_ssa[i][0] = AIRct[0]; + for (int ndx = 1; ndx < 8; ++ndx) { + list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; + } + } + + list->inum = inum; +} + +/* ---------------------------------------------------------------------- + comparison function invoked by qsort() + accesses static class member ssaAIRptr, set before call to qsort() +------------------------------------------------------------------------- */ + +static int cmp_ssaAIR(const void *iptr, const void *jptr) +{ + int i = *((int *) iptr); + int j = *((int *) jptr); + if (ssaAIRptr[i] < ssaAIRptr[j]) return -1; + if (ssaAIRptr[i] > ssaAIRptr[j]) return 1; + return 0; +} + diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.h b/src/USER-DPD/npair_half_bin_newton_ssa.h new file mode 100644 index 0000000000..13347b33b0 --- /dev/null +++ b/src/USER-DPD/npair_half_bin_newton_ssa.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newton/ssa, + NPairHalfBinNewtonSSA, + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_SSA) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTON_SSA_H +#define LMP_NPAIR_HALF_BIN_NEWTON_SSA_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewtonSSA : public NPair { + public: + NPairHalfBinNewtonSSA(class LAMMPS *); + ~NPairHalfBinNewtonSSA() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-DPD/npair_halffull_newton_ssa.cpp b/src/USER-DPD/npair_halffull_newton_ssa.cpp new file mode 100644 index 0000000000..f09a2c3ae1 --- /dev/null +++ b/src/USER-DPD/npair_halffull_newton_ssa.cpp @@ -0,0 +1,132 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos and Timothy I. Mattox (Engility Corporation) +------------------------------------------------------------------------- */ + +#include "npair_halffull_newton_ssa.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; + +// allocate space for static class variable +// prototype for non-class function + +static int *ssaAIRptr; +static int cmp_ssaAIR(const void *, const void *); + +/* ---------------------------------------------------------------------- */ + +NPairHalffullNewtonSSA::NPairHalffullNewtonSSA(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build half list from full list for use by Shardlow Spliting Algorithm + 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 +------------------------------------------------------------------------- */ + +void NPairHalffullNewtonSSA::build(NeighList *list) +{ + int i,j,ii,jj,n,jnum,joriginal; + int *neighptr,*jlist; + + int nlocal = atom->nlocal; + int *ssaAIR = atom->ssaAIR; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_full = list->listfull->ilist; + int *numneigh_full = list->listfull->numneigh; + int **firstneigh_full = list->listfull->firstneigh; + int inum_full = list->listfull->inum; + + int inum = 0; + ipage->reset(); + + // loop over parent full list + + for (ii = 0; ii < inum_full; ii++) { + int AIRct[8] = { 0 }; + n = 0; + neighptr = ipage->vget(); + + i = ilist_full[ii]; + + // loop over full neighbor list + + jlist = firstneigh_full[i]; + jnum = numneigh_full[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (j < nlocal) { + if (i > j) continue; + ++(AIRct[0]); + } else { + if (ssaAIR[j] < 2) continue; // skip ghost atoms not in AIR + ++(AIRct[ssaAIR[j] - 1]); + } + neighptr[n++] = joriginal; + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + // sort the locals+ghosts in the neighbor list by their ssaAIR number + + ssaAIRptr = atom->ssaAIR; + qsort(&(neighptr[0]), n, sizeof(int), cmp_ssaAIR); + + // do a prefix sum on the counts to turn them into indexes + + list->ndxAIR_ssa[i][0] = AIRct[0]; + for (int ndx = 1; ndx < 8; ++ndx) { + list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; + } + } + + list->inum = inum; +} + +/* ---------------------------------------------------------------------- + comparison function invoked by qsort() + accesses static class member ssaAIRptr, set before call to qsort() +------------------------------------------------------------------------- */ + +static int cmp_ssaAIR(const void *iptr, const void *jptr) +{ + int i = *((int *) iptr); + int j = *((int *) jptr); + if (ssaAIRptr[i] < ssaAIRptr[j]) return -1; + if (ssaAIRptr[i] > ssaAIRptr[j]) return 1; + return 0; +} + diff --git a/src/USER-DPD/npair_halffull_newton_ssa.h b/src/USER-DPD/npair_halffull_newton_ssa.h new file mode 100644 index 0000000000..4935349f77 --- /dev/null +++ b/src/USER-DPD/npair_halffull_newton_ssa.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(halffull/newton/ssa, + NPairHalffullNewtonSSA, + NP_HALFFULL | NP_NSQ | NP_BIN | NP_MULTI | NP_NEWTON | + NP_ORTHO | NP_TRI | NP_SSA) + +#else + +#ifndef LMP_NPAIR_HALFFULL_NEWTON_SSA_H +#define LMP_NPAIR_HALFFULL_NEWTON_SSA_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalffullNewtonSSA : public NPair { + public: + NPairHalffullNewtonSSA(class LAMMPS *); + ~NPairHalffullNewtonSSA() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp new file mode 100644 index 0000000000..4c548c783c --- /dev/null +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp @@ -0,0 +1,64 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos and Timothy I. Mattox (Engility Corporation) +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_2d_newton_ssa.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin2dNewtonSSA::NStencilHalfBin2dNewtonSSA(LAMMPS *lmp) : + NStencilSSA(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff + stencil = bins whose closest corner to central bin is within cutoff + sx,sy,sz = bin bounds = furthest the stencil could possibly extend + 3d creates xyz stencil, 2d creates xy stencil + for half list with newton on: + stencil is bins to the "upper right" of central bin + stencil does not include self + additionally, includes the bins beyond nstencil that are needed + to locate all the Active Interaction Region (AIR) ghosts for SSA +------------------------------------------------------------------------- */ + +void NStencilHalfBin2dNewtonSSA::create() +{ + int i,j,pos = 0; + + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (j > 0 || (j == 0 && i > 0)) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[pos++] = j*mbinx + i; + + nstencil_half = pos; // record where normal half stencil ends + + // include additional bins for AIR ghosts only + + for (j = -sy; j <= 0; j++) + for (i = -sx; i <= sx; i++) { + if (j == 0 && i > 0) continue; + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[pos++] = j*mbinx + i; + } + + nstencil = pos; // record where full stencil ends +} diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h new file mode 100644 index 0000000000..30901bb3e2 --- /dev/null +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/2d/newton/ssa, + NStencilHalfBin2dNewtonSSA, + NS_HALF | NS_BIN | NS_2D | NS_NEWTON | NS_SSA | NS_ORTHO) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_2D_NEWTON_SSA_H +#define LMP_NSTENCIL_HALF_BIN_2D_NEWTON_SSA_H + +#include "nstencil_ssa.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin2dNewtonSSA : public NStencilSSA { + public: + NStencilHalfBin2dNewtonSSA(class LAMMPS *); + ~NStencilHalfBin2dNewtonSSA() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp new file mode 100644 index 0000000000..4b8bd27016 --- /dev/null +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp @@ -0,0 +1,74 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing authors: + James Larentzos and Timothy I. Mattox (Engility Corporation) +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_3d_newton_ssa.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin3dNewtonSSA::NStencilHalfBin3dNewtonSSA(LAMMPS *lmp) : + NStencilSSA(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff + stencil = bins whose closest corner to central bin is within cutoff + sx,sy,sz = bin bounds = furthest the stencil could possibly extend + 3d creates xyz stencil, 2d creates xy stencil + for half list with newton on: + stencil is bins to the "upper right" of central bin + stencil does not include self + additionally, includes the bins beyond nstencil that are needed + to locate all the Active Interaction Region (AIR) ghosts for SSA +------------------------------------------------------------------------- */ + +void NStencilHalfBin3dNewtonSSA::create() +{ + int i,j,k,pos = 0; + + for (k = 0; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (k > 0 || j > 0 || (j == 0 && i > 0)) + if (bin_distance(i,j,k) < cutneighmaxsq) + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + + nstencil_half = pos; // record where normal half stencil ends + + // include additional bins for AIR ghosts only + + for (k = -sz; k < 0; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + + // For k==0, make sure to skip already included bins + + k = 0; + for (j = -sy; j <= 0; j++) + for (i = -sx; i <= sx; i++) { + if (j == 0 && i > 0) continue; + if (bin_distance(i,j,k) < cutneighmaxsq) + stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; + } + + nstencil = pos; // record where full stencil ends +} diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h new file mode 100644 index 0000000000..7765b256d3 --- /dev/null +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/3d/newton/ssa, + NStencilHalfBin3dNewtonSSA, + NS_HALF | NS_BIN | NS_3D | NS_NEWTON | NS_SSA | NS_ORTHO) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_3D_NEWTON_SSA_H +#define LMP_NSTENCIL_HALF_BIN_3D_NEWTON_SSA_H + +#include "nstencil_ssa.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin3dNewtonSSA : public NStencilSSA { + public: + NStencilHalfBin3dNewtonSSA(class LAMMPS *); + ~NStencilHalfBin3dNewtonSSA() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/neigh_gran.h b/src/USER-DPD/nstencil_ssa.h similarity index 67% rename from src/neigh_gran.h rename to src/USER-DPD/nstencil_ssa.h index 1538f7662a..9fcd19ee26 100644 --- a/src/neigh_gran.h +++ b/src/USER-DPD/nstencil_ssa.h @@ -11,12 +11,26 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#ifndef LMP_NSTENCIL_SSA_H +#define LMP_NSTENCIL_SSA_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilSSA : public NStencil { + public: + NStencilSSA(class LAMMPS *lmp) : NStencil(lmp) { } + ~NStencilSSA() {} + virtual void create() = 0; + + int nstencil_half; // where the half stencil ends +}; + +} + +#endif + /* ERROR/WARNING messages: -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - */ diff --git a/src/USER-DPD/pair_dpd_fdt.cpp b/src/USER-DPD/pair_dpd_fdt.cpp index 3b5804ff8e..cea5b87404 100644 --- a/src/USER-DPD/pair_dpd_fdt.cpp +++ b/src/USER-DPD/pair_dpd_fdt.cpp @@ -320,11 +320,9 @@ void PairDPDfdt::init_style() splitFDT_flag = false; int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->ssa = 0; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"shardlow") == 0){ splitFDT_flag = true; - neighbor->requests[irequest]->ssa = 1; } } diff --git a/src/USER-DPD/pair_dpd_fdt_energy.cpp b/src/USER-DPD/pair_dpd_fdt_energy.cpp index 99ba4de582..2041405467 100644 --- a/src/USER-DPD/pair_dpd_fdt_energy.cpp +++ b/src/USER-DPD/pair_dpd_fdt_energy.cpp @@ -408,11 +408,9 @@ void PairDPDfdtEnergy::init_style() splitFDT_flag = false; int irequest = neighbor->request(this,instance_me); - neighbor->requests[irequest]->ssa = 0; for (int i = 0; i < modify->nfix; i++) if (strcmp(modify->fix[i]->style,"shardlow") == 0){ splitFDT_flag = true; - neighbor->requests[irequest]->ssa = 1; } bool eos_flag = false; diff --git a/src/USER-INTEL/Install.sh b/src/USER-INTEL/Install.sh index 79cc1158e9..736059aa06 100644 --- a/src/USER-INTEL/Install.sh +++ b/src/USER-INTEL/Install.sh @@ -3,10 +3,6 @@ mode=$1 -# enforce using portable C locale -LC_ALL=C -export LC_ALL - # arg1 = file, arg2 = file it depends on action () { @@ -44,6 +40,10 @@ action intel_preprocess.h action intel_buffers.h action intel_buffers.cpp action math_extra_intel.h +action nbin_intel.h +action nbin_intel.cpp +action npair_intel.h +action npair_intel.cpp action intel_simd.h pair_sw_intel.cpp action intel_intrinsics.h pair_tersoff_intel.cpp action verlet_lrt_intel.h pppm.cpp @@ -58,18 +58,10 @@ if (test $mode = 1) then sed -i -e 's|^PKG_INC =[ \t]*|&-DLMP_USER_INTEL |' ../Makefile.package fi - # force rebuild of files with LMP_USER_INTEL switch - - touch ../accelerator_intel.h - elif (test $mode = 0) then if (test -e ../Makefile.package) then sed -i -e 's/[^ \t]*INTEL[^ \t]* //' ../Makefile.package fi - # force rebuild of files with LMP_USER_INTEL switch - - touch ../accelerator_intel.h - fi diff --git a/src/USER-INTEL/fix_intel.cpp b/src/USER-INTEL/fix_intel.cpp index 226396681f..06bd23abcc 100644 --- a/src/USER-INTEL/fix_intel.cpp +++ b/src/USER-INTEL/fix_intel.cpp @@ -317,8 +317,6 @@ void FixIntel::init() error->all(FLERR, "Currently, cannot use more than one intel style with hybrid."); - neighbor->fix_intel = (void *)this; - check_neighbor_intel(); if (_precision_mode == PREC_MODE_SINGLE) _single_buffers->zero_ev(); diff --git a/src/USER-INTEL/intel_buffers.cpp b/src/USER-INTEL/intel_buffers.cpp index 4980cdcac8..c81dffec83 100644 --- a/src/USER-INTEL/intel_buffers.cpp +++ b/src/USER-INTEL/intel_buffers.cpp @@ -26,18 +26,17 @@ IntelBuffers::IntelBuffers(class LAMMPS *lmp_in) : _buf_size(0), _buf_local_size(0) { _list_alloc_atoms = 0; _ntypes = 0; - _off_map_maxlocal = 0; + _off_map_listlocal = 0; _ccachex = 0; - _host_nmax = 0; #ifdef _LMP_INTEL_OFFLOAD _separate_buffers = 0; _off_f = 0; _off_map_ilist = 0; _off_map_nmax = 0; - _off_map_maxhead = 0; _off_list_alloc = false; _off_threads = 0; _off_ccache = 0; + _host_nmax = 0; #endif } @@ -173,21 +172,15 @@ void IntelBuffers::free_nmax() const int * tag = _off_map_tag; const int * special = _off_map_special; const int * nspecial = _off_map_nspecial; - const int * bins = _off_map_bins; - const int * binpacked = _binpacked; - if (tag != 0 && special != 0 && nspecial !=0 && bins != 0) { + if (tag != 0 && special != 0 && nspecial !=0) { #pragma offload_transfer target(mic:_cop) \ nocopy(tag:alloc_if(0) free_if(1)) \ - nocopy(special,nspecial:alloc_if(0) free_if(1)) \ - nocopy(bins,binpacked:alloc_if(0) free_if(1)) + nocopy(special,nspecial:alloc_if(0) free_if(1)) } _off_map_nmax = 0; - } - #endif - if (_host_nmax > 0) { - lmp->memory->destroy(_binpacked); _host_nmax = 0; } + #endif } /* ---------------------------------------------------------------------- */ @@ -195,12 +188,11 @@ void IntelBuffers::free_nmax() template void IntelBuffers::_grow_nmax(const int offload_end) { + #ifdef _LMP_INTEL_OFFLOAD free_nmax(); int size = lmp->atom->nmax; _host_nmax = size; - lmp->memory->create(_binpacked, _host_nmax, "_binpacked"); - #ifdef _LMP_INTEL_OFFLOAD if (!offload_end) return; int *special, *nspecial; int tag_length, special_length, nspecial_length; @@ -220,10 +212,7 @@ void IntelBuffers::_grow_nmax(const int offload_end) else tag_length = 1; int *tag = lmp->atom->tag; - int *bins = lmp->neighbor->bins; - int * binpacked = _binpacked; #pragma offload_transfer target(mic:_cop) \ - nocopy(bins,binpacked:length(size) alloc_if(1) free_if(0)) \ nocopy(tag:length(tag_length) alloc_if(1) free_if(0)) \ nocopy(special:length(special_length) alloc_if(1) free_if(0)) \ nocopy(nspecial:length(nspecial_length) alloc_if(1) free_if(0)) @@ -231,18 +220,16 @@ void IntelBuffers::_grow_nmax(const int offload_end) _off_map_special = special; _off_map_nspecial = nspecial; _off_map_nmax = size; - _off_map_bins = bins; #endif } /* ---------------------------------------------------------------------- */ template -void IntelBuffers::free_local() +void IntelBuffers::free_list_local() { - if (_off_map_maxlocal > 0) { + if (_off_map_listlocal > 0) { int * cnumneigh = _cnumneigh; - int * atombin = _atombin; #ifdef _LMP_INTEL_OFFLOAD if (_off_map_ilist != NULL) { const int * ilist = _off_map_ilist; @@ -250,40 +237,36 @@ void IntelBuffers::free_local() _off_map_ilist = NULL; if (numneigh != 0 && ilist != 0) { #pragma offload_transfer target(mic:_cop) \ - nocopy(ilist,numneigh,cnumneigh,atombin:alloc_if(0) free_if(1)) + nocopy(ilist,numneigh,cnumneigh:alloc_if(0) free_if(1)) } } #endif lmp->memory->destroy(cnumneigh); - lmp->memory->destroy(atombin); - _off_map_maxlocal = 0; + _off_map_listlocal = 0; } } /* ---------------------------------------------------------------------- */ template -void IntelBuffers::_grow_local(NeighList *list, - const int offload_end) +void IntelBuffers::_grow_list_local(NeighList *list, + const int offload_end) { - free_local(); + free_list_local(); int size = list->get_maxlocal(); lmp->memory->create(_cnumneigh, size, "_cnumneigh"); - lmp->memory->create(_atombin, size, "_atombin"); - _off_map_maxlocal = size; + _off_map_listlocal = size; #ifdef _LMP_INTEL_OFFLOAD if (offload_end > 0) { int * numneigh = list->numneigh; int * ilist = list->ilist; int * cnumneigh = _cnumneigh; - int * atombin = _atombin; - if (cnumneigh != 0 && atombin != 0) { + if (cnumneigh != 0) { #pragma offload_transfer target(mic:_cop) \ nocopy(ilist:length(size) alloc_if(1) free_if(0)) \ nocopy(numneigh:length(size) alloc_if(1) free_if(0)) \ - nocopy(cnumneigh:length(size) alloc_if(1) free_if(0)) \ - nocopy(atombin:length(size) alloc_if(1) free_if(0)) + nocopy(cnumneigh:length(size) alloc_if(1) free_if(0)) } _off_map_ilist = ilist; _off_map_numneigh = numneigh; @@ -293,39 +276,6 @@ void IntelBuffers::_grow_local(NeighList *list, /* ---------------------------------------------------------------------- */ -template -void IntelBuffers::free_binhead() -{ - #ifdef _LMP_INTEL_OFFLOAD - if (_off_map_maxhead > 0) { - const int * binhead = _off_map_binhead; - if (binhead !=0) { - #pragma offload_transfer target(mic:_cop) \ - nocopy(binhead:alloc_if(0) free_if(1)) - } - _off_map_maxhead = 0; - } - #endif -} - -/* ---------------------------------------------------------------------- */ - -template -void IntelBuffers::_grow_binhead() -{ - #ifdef _LMP_INTEL_OFFLOAD - free_binhead(); - int * binhead = lmp->neighbor->binhead; - const int maxhead = lmp->neighbor->maxhead; - #pragma offload_transfer target(mic:_cop) \ - nocopy(binhead:length(maxhead+1) alloc_if(1) free_if(0)) - _off_map_binhead = binhead; - _off_map_maxhead = maxhead; - #endif -} - -/* ---------------------------------------------------------------------- */ - template void IntelBuffers::free_nbor_list() { @@ -333,11 +283,8 @@ void IntelBuffers::free_nbor_list() #ifdef _LMP_INTEL_OFFLOAD if (_off_list_alloc) { int * list_alloc = _list_alloc; - int * stencil = _off_map_stencil; - if (list_alloc != 0 && stencil != 0) { - #pragma offload_transfer target(mic:_cop) \ - nocopy(list_alloc:alloc_if(0) free_if(1)) - } + #pragma offload_transfer target(mic:_cop) \ + nocopy(list_alloc:alloc_if(0) free_if(1)) _off_list_alloc = false; } #endif @@ -364,33 +311,16 @@ void IntelBuffers::_grow_nbor_list(NeighList *list, #ifdef _LMP_INTEL_OFFLOAD if (offload_end > 0) { int * list_alloc =_list_alloc; - int * stencil = list->stencil; if (list_alloc != NULL) { #pragma offload_transfer target(mic:_cop) \ - in(stencil:length(list->maxstencil) alloc_if(1) free_if(0)) \ nocopy(list_alloc:length(list_alloc_size) alloc_if(1) free_if(0)) - _off_map_stencil = stencil; _off_list_alloc = true; } } #endif } -template -void IntelBuffers::_grow_stencil(NeighList *list) -{ - #ifdef _LMP_INTEL_OFFLOAD - int * stencil = _off_map_stencil; - #pragma offload_transfer target(mic:_cop) \ - nocopy(stencil:alloc_if(0) free_if(1)) - stencil = list->stencil; - #pragma offload_transfer target(mic:_cop) \ - in(stencil:length(list->maxstencil) alloc_if(1) free_if(0)) - _off_map_stencil = stencil; - #endif -} - /* ---------------------------------------------------------------------- */ template @@ -544,7 +474,6 @@ double IntelBuffers::memory_usage(const int nthreads) if (_off_f) tmem += fstride*_off_threads * sizeof(vec3_acc_t); #endif - tmem += _off_map_maxlocal * sizeof(int) * 2; tmem += (_list_alloc_atoms + _off_threads) * get_max_nbors() * sizeof(int); tmem += _ntypes * _ntypes * sizeof(int); diff --git a/src/USER-INTEL/intel_buffers.h b/src/USER-INTEL/intel_buffers.h index df72234dbe..3462d013a1 100644 --- a/src/USER-INTEL/intel_buffers.h +++ b/src/USER-INTEL/intel_buffers.h @@ -61,50 +61,35 @@ class IntelBuffers { } void free_buffers(); - + void free_nmax(); + inline void set_bininfo(int *atombin, int *binpacked) + { _atombin = atombin; _binpacked = binpacked; } inline void grow(const int nall, const int nlocal, const int nthreads, const int offload_end) { if (nall >= _buf_size || nlocal >= _buf_local_size) _grow(nall, nlocal, nthreads, offload_end); + #ifdef _LMP_INTEL_OFFLOAD + if (lmp->atom->nmax > _host_nmax) + _grow_nmax(offload_end); + #endif } inline void free_all_nbor_buffers() { free_nbor_list(); free_nmax(); - free_binhead(); - free_local(); + free_list_local(); } - inline void grow_nbor(NeighList *list, const int nlocal, const int nthreads, + inline void grow_list(NeighList *list, const int nlocal, const int nthreads, const int offload_end, const int pack_width=1) { - grow_local(list, offload_end); - grow_nmax(offload_end); - if (offload_end) - grow_binhead(); + grow_list_local(list, offload_end); grow_nbor_list(list, nlocal, nthreads, offload_end, pack_width); } - void free_nmax(); - - inline void grow_nmax(const int offload_end) { - if (lmp->atom->nmax > _host_nmax) - _grow_nmax(offload_end); - } - - void free_local(); - - inline void grow_local(NeighList *list, const int offload_end) { - if (list->get_maxlocal() > _off_map_maxlocal) - _grow_local(list, offload_end); - } - - void free_binhead(); - - inline void grow_binhead() { - #ifdef _LMP_INTEL_OFFLOAD - if (lmp->neighbor->maxhead > _off_map_maxhead) - _grow_binhead(); - #endif + void free_list_local(); + inline void grow_list_local(NeighList *list, const int offload_end) { + if (list->get_maxlocal() > _off_map_listlocal) + _grow_list_local(list, offload_end); } void free_ccache(); @@ -134,19 +119,15 @@ class IntelBuffers { const int pack_width) { if (nlocal > _list_alloc_atoms) _grow_nbor_list(list, nlocal, nthreads, offload_end, pack_width); - #ifdef _LMP_INTEL_OFFLOAD - else if (offload_end > 0 && _off_map_stencil != list->stencil) - _grow_stencil(list); - #endif } void set_ntypes(const int ntypes); inline int * firstneigh(const NeighList *list) { return _list_alloc; } inline int * cnumneigh(const NeighList *list) { return _cnumneigh; } - inline int * get_atombin() { return _atombin; } inline int * get_binpacked() { return _binpacked; } + inline atom_t * get_x(const int offload = 1) { #ifdef _LMP_INTEL_OFFLOAD if (_separate_buffers && offload == 0) return _host_x; @@ -271,13 +252,10 @@ class IntelBuffers { flt_t *_q; quat_t *_quat; vec3_acc_t * _f; - int _off_threads, _off_map_maxlocal; + int _off_threads, _off_map_listlocal; int _list_alloc_atoms; - int * _list_alloc; - int * _cnumneigh; - int * _atombin; - int * _binpacked; + int *_list_alloc, *_cnumneigh, *_atombin, *_binpacked; flt_t **_cutneighsq; int _ntypes; @@ -296,26 +274,24 @@ class IntelBuffers { flt_t *_host_q; quat_t *_host_quat; vec3_acc_t *_off_f; - int _off_map_nmax, _off_map_maxhead, _cop, _off_ccache; + int _off_map_nmax, _cop, _off_ccache; int *_off_map_ilist; - int *_off_map_stencil, *_off_map_special, *_off_map_nspecial, *_off_map_tag; - int *_off_map_binhead, *_off_map_bins, *_off_map_numneigh; + int *_off_map_special, *_off_map_nspecial, *_off_map_tag; + int *_off_map_numneigh; bool _off_list_alloc; - int _need_tag; + int _need_tag, _host_nmax; #endif - int _buf_size, _buf_local_size, _host_nmax; + int _buf_size, _buf_local_size; _alignvar(acc_t _ev_global[8],64); _alignvar(acc_t _ev_global_host[8],64); void _grow(const int nall, const int nlocal, const int nthreads, const int offload_end); void _grow_nmax(const int offload_end); - void _grow_local(NeighList *list, const int offload_end); - void _grow_binhead(); + void _grow_list_local(NeighList *list, const int offload_end); void _grow_nbor_list(NeighList *list, const int nlocal, const int nthreads, const int offload_end, const int pack_width); - void _grow_stencil(NeighList *list); }; } diff --git a/src/USER-INTEL/nbin_intel.cpp b/src/USER-INTEL/nbin_intel.cpp new file mode 100644 index 0000000000..8dceafd3ab --- /dev/null +++ b/src/USER-INTEL/nbin_intel.cpp @@ -0,0 +1,253 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "nbin_intel.h" +#include "atom.h" +#include "group.h" +#include "domain.h" +#include "comm.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NBinIntel::NBinIntel(LAMMPS *lmp) : NBinStandard(lmp) { + int ifix = modify->find_fix("package_intel"); + if (ifix < 0) + error->all(FLERR, + "The 'package intel' command is required for /intel styles"); + _fix = static_cast(modify->fix[ifix]); + _precision_mode = _fix->precision(); + _atombin = NULL; + _binpacked = NULL; + #ifdef _LMP_INTEL_OFFLOAD + _cop = _fix->coprocessor_number(); + _offload_alloc = 0; + #endif +} + +/* ---------------------------------------------------------------------- */ + +NBinIntel::~NBinIntel() { + #ifdef _LMP_INTEL_OFFLOAD + if (_offload_alloc) { + const int * binhead = this->binhead; + const int * bins = this->bins; + const int * _atombin = this->_atombin; + const int * _binpacked = this->_binpacked; + #pragma offload_transfer target(mic:_cop) \ + nocopy(binhead,bins,_atombin,_binpacked:alloc_if(0) free_if(1)) + } + #endif +} + +/* ---------------------------------------------------------------------- + setup for bin_atoms() +------------------------------------------------------------------------- */ + +void NBinIntel::bin_atoms_setup(int nall) +{ + // binhead = per-bin vector, mbins in length + // add 1 bin for USER-INTEL package + + if (mbins > maxbin) { + #ifdef _LMP_INTEL_OFFLOAD + if (_offload_alloc) { + const int * binhead = this->binhead; + #pragma offload_transfer target(mic:_cop) \ + nocopy(binhead:alloc_if(0) free_if(1)) + } + #endif + + maxbin = mbins; + memory->destroy(binhead); + memory->create(binhead,maxbin+1,"neigh:binhead"); + + #ifdef _LMP_INTEL_OFFLOAD + if (_fix->offload_balance() != 0) { + int * binhead = this->binhead; + #pragma offload_transfer target(mic:_cop) \ + nocopy(binhead:length(maxbin+1) alloc_if(1) free_if(0)) + } + #endif + last_bin_memory = update->ntimestep; + } + + // bins = per-atom vector + + if (nall > maxatom) { + maxatom = nall; + + #ifdef _LMP_INTEL_OFFLOAD + if (_offload_alloc) { + const int * bins = this->bins; + const int * _atombin = this->_atombin; + const int * _binpacked = this->_binpacked; + #pragma offload_transfer target(mic:_cop) \ + nocopy(bins,_atombin,_binpacked:alloc_if(0) free_if(1)) + } + #endif + memory->destroy(bins); + memory->destroy(_atombin); + memory->destroy(_binpacked); + + memory->create(bins,maxatom,"neigh:bins"); + memory->create(_atombin,maxatom,"neigh:bins"); + memory->create(_binpacked,maxatom,"neigh:bins"); + #ifdef _LMP_INTEL_OFFLOAD + if (_fix->offload_balance() != 0) { + const int * bins = this->bins; + const int * _atombin = this->_atombin; + const int * _binpacked = this->_binpacked; + #pragma offload_transfer target(mic:_cop) \ + nocopy(bins,_atombin,_binpacked:length(maxatom) alloc_if(1) free_if(0)) + _offload_alloc=1; + } + #endif + + if (_precision_mode == FixIntel::PREC_MODE_MIXED) + _fix->get_mixed_buffers()->set_bininfo(_atombin,_binpacked); + else if (_precision_mode == FixIntel::PREC_MODE_SINGLE) + _fix->get_single_buffers()->set_bininfo(_atombin,_binpacked); + else + _fix->get_double_buffers()->set_bininfo(_atombin,_binpacked); + + last_bin_memory = update->ntimestep; + } + + last_bin = update->ntimestep; +} + +/* ---------------------------------------------------------------------- + bin owned and ghost atoms +------------------------------------------------------------------------- */ + +void NBinIntel::bin_atoms() +{ + if (_precision_mode == FixIntel::PREC_MODE_MIXED) + bin_atoms(_fix->get_mixed_buffers()); + else if (_precision_mode == FixIntel::PREC_MODE_SINGLE) + bin_atoms(_fix->get_single_buffers()); + else + bin_atoms(_fix->get_double_buffers()); +} + +template +void NBinIntel::bin_atoms(IntelBuffers * buffers) { + const int nlocal = atom->nlocal; + const int nall = nlocal + atom->nghost; + const int aend = _fix->offload_end_neighbor(); + + + // ---------- Sanity check for padding -------------- + { + const flt_t dx = (INTEL_BIGP - bboxhi[0]); + const flt_t dy = (INTEL_BIGP - bboxhi[1]); + const flt_t dz = (INTEL_BIGP - bboxhi[2]); + if (dx * dx + dy * dy + dz * dz < + static_cast(neighbor->cutneighmaxsq)) + error->one(FLERR, + "Intel package expects no atoms within cutoff of {1e15,1e15,1e15}."); + } + + // ---------- Grow and cast/pack buffers ------------- + _fix->start_watch(TIME_PACK); + buffers->grow(nall, atom->nlocal, comm->nthreads, aend); + + ATOM_T biga; + biga.x = INTEL_BIGP; + biga.y = INTEL_BIGP; + biga.z = INTEL_BIGP; + biga.w = 1; + buffers->get_x()[nall] = biga; + + const int nthreads = comm->nthreads; + #if defined(_OPENMP) + #pragma omp parallel default(none) shared(buffers) + #endif + { + int ifrom, ito, tid; + IP_PRE_omp_range_id_align(ifrom, ito, tid, nall, nthreads, + sizeof(ATOM_T)); + buffers->thr_pack(ifrom, ito, 0); + } + _fix->stop_watch(TIME_PACK); + + + // ---------- Bin Atoms ------------- + _fix->start_watch(TIME_HOST_NEIGHBOR); + const ATOM_T * _noalias const x = buffers->get_x(); + int * _noalias const atombin = this->_atombin; + int * _noalias const binpacked = this->_binpacked; + + + const double sboxlo0 = bboxlo[0] + mbinxlo/bininvx; + const double sboxlo1 = bboxlo[1] + mbinylo/bininvy; + const double sboxlo2 = bboxlo[2] + mbinzlo/bininvz; + + int i, ibin; + + for (i = 0; i < mbins; i++) binhead[i] = -1; + + int *mask = atom->mask; + + if (includegroup) { + int bitmask = group->bitmask[includegroup]; + for (i = nall-1; i >= nlocal; i--) { + if (mask[i] & bitmask) { + ibin = coord2bin(atom->x[i]); + bins[i] = binhead[ibin]; + binhead[ibin] = i; + } + } + for (i = atom->nfirst-1; i >= 0; i--) { + ibin = coord2bin(atom->x[i]); + atombin[i] = ibin; + bins[i] = binhead[ibin]; + binhead[ibin] = i; + } + } else { + for (i = nall-1; i >= nlocal; i--) { + ibin = coord2bin(atom->x[i]); + bins[i] = binhead[ibin]; + binhead[ibin] = i; + } + for (i = nlocal-1; i >= 0; i--) { + ibin = coord2bin(atom->x[i]); + atombin[i]=ibin; + bins[i] = binhead[ibin]; + binhead[ibin] = i; + } + } + int newhead = 0; + for (i = 0; i < mbins; i++) { + int j = binhead[i]; + binhead[i] = newhead; + for ( ; j >= 0; j = bins[j]) + binpacked[newhead++] = j; + } + binhead[mbins] = newhead; +} + +/* ---------------------------------------------------------------------- */ + +bigint NBinIntel::memory_usage() +{ + return NBinStandard::memory_usage() + maxatom*2*sizeof(int); +} diff --git a/src/USER-INTEL/nbin_intel.h b/src/USER-INTEL/nbin_intel.h new file mode 100644 index 0000000000..d96f31885e --- /dev/null +++ b/src/USER-INTEL/nbin_intel.h @@ -0,0 +1,69 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NBIN_CLASS + +NBinStyle(intel, + NBinIntel, + NB_INTEL) + +#else + +#ifndef LMP_NBIN_INTEL_H +#define LMP_NBIN_INTEL_H + +#include "nbin_standard.h" +#include "fix_intel.h" +#include "memory.h" + +namespace LAMMPS_NS { + +class NBinIntel : public NBinStandard { + public: + NBinIntel(class LAMMPS *); + ~NBinIntel(); + void bin_atoms_setup(int); + void bin_atoms(); + int * get_binpacked() { return _binpacked; } + + private: + FixIntel *_fix; + int *_atombin, *_binpacked; + int _precision_mode; + bigint memory_usage(); + + template + void bin_atoms(IntelBuffers *); + + #ifdef _LMP_INTEL_OFFLOAD + int _cop, _offload_alloc; + #endif +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +E: The 'package intel' command is required for /intel styles + +Self-explanatory. + +E: Intel package expects no atoms within cutoff of {1e15,1e15,1e15}. + +The Intel package can make use of dummy atoms for padding with a large position +that should not be within the cutoff. + +*/ diff --git a/src/USER-INTEL/neigh_half_bin_intel.cpp b/src/USER-INTEL/neigh_half_bin_intel.cpp deleted file mode 100644 index c8d4657818..0000000000 --- a/src/USER-INTEL/neigh_half_bin_intel.cpp +++ /dev/null @@ -1,2455 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing author: W. Michael Brown (Intel) -------------------------------------------------------------------------- */ - -//#define OUTER_CHUNK 1 - -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "comm.h" -#include "group.h" -#include "fix_intel.h" - -#if defined(_OPENMP) -#include -#endif - -#ifdef LMP_USE_AVXCD -#include "intel_simd.h" -#endif - -#ifdef OUTER_CHUNK -#include "intel_simd.h" -#endif - -using namespace LAMMPS_NS; - -#ifdef _LMP_INTEL_OFFLOAD -#pragma offload_attribute(push,target(mic)) -#endif - -#define ofind_special(which, special, nspecial, i, tag) \ -{ \ - which = 0; \ - const int n1 = nspecial[i * 3]; \ - const int n2 = nspecial[i * 3 + 1]; \ - const int n3 = nspecial[i * 3 + 2]; \ - const tagint *sptr = special + i * maxspecial; \ - for (int s = 0; s < n3; s++) { \ - if (sptr[s] == tag) { \ - if (s < n1) { \ - which = 1; \ - } else if (s < n2) { \ - which = 2; \ - } else { \ - which = 3; \ - } \ - } \ - } \ -} - -#define ominimum_image_check(answer, dx, dy, dz) \ -{ \ - answer = 0; \ - if (xperiodic && fabs(dx) > xprd_half) answer = 1; \ - if (yperiodic && fabs(dy) > yprd_half) answer = 1; \ - if (zperiodic && fabs(dz) > zprd_half) answer = 1; \ -} - -#define dminimum_image_check(answer, dx, dy, dz) \ -{ \ - answer = 0; \ - if (domain->xperiodic && fabs(dx) > domain->xprd_half) answer = 1; \ - if (domain->yperiodic && fabs(dy) > domain->yprd_half) answer = 1; \ - if (domain->zperiodic && fabs(dz) > domain->zprd_half) answer = 1; \ -} - -#ifdef _LMP_INTEL_OFFLOAD -#pragma offload_attribute(pop) -#endif - -template -void Neighbor::bin_atoms(void * xin, int * _noalias const atombin, - int * _noalias const binpacked) { - const ATOM_T * _noalias const x = (const ATOM_T * _noalias const)xin; - int nlocal = atom->nlocal; - const int nall = nlocal + atom->nghost; - - const double sboxlo0 = bboxlo[0] + mbinxlo/bininvx; - const double sboxlo1 = bboxlo[1] + mbinylo/bininvy; - const double sboxlo2 = bboxlo[2] + mbinzlo/bininvz; - - int i, ibin; - - for (i = 0; i < mbins; i++) binhead[i] = -1; - - int *mask = atom->mask; - - if (includegroup) { - int bitmask = group->bitmask[includegroup]; - for (i = nall-1; i >= nlocal; i--) { - if (mask[i] & bitmask) { - ibin = coord2bin(atom->x[i]); - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - } - for (i = atom->nfirst-1; i >= 0; i--) { - ibin = coord2bin(atom->x[i]); - atombin[i] = ibin; - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - } else { - for (i = nall-1; i >= nlocal; i--) { - ibin = coord2bin(atom->x[i]); - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - for (i = nlocal-1; i >= 0; i--) { - ibin = coord2bin(atom->x[i]); - atombin[i]=ibin; - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - } - int newhead = 0; - for (i = 0; i < mbins; i++) { - int j = binhead[i]; - binhead[i] = newhead; - for ( ; j >= 0; j = bins[j]) - binpacked[newhead++] = j; - } - binhead[mbins] = newhead; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_no_newton_intel(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - list->inum = nlocal; - - // Get fix for intel stuff - FixIntel *fix = static_cast(fix_intel); - - const int off_end = fix->offload_end_neighbor(); - int host_start = off_end;; - #ifdef _LMP_INTEL_OFFLOAD - if (fix->full_host_list()) host_start = 0; - if (exclude) - error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); - #endif - if (list->nstencil > INTEL_MAX_STENCIL_CHECK) - error->all(FLERR, "Too many neighbor bins for USER-INTEL package."); - - int need_ic = 0; - if (atom->molecular) - dminimum_image_check(need_ic, cutneighmax, cutneighmax, cutneighmax); - - if (need_ic) { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - hbnni(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnni(0, list, fix->get_mixed_buffers(), - host_start, nlocal,fix); - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - hbnni(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnni(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } else { - hbnni(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnni(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } else { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - hbnni(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnni(0, list, fix->get_mixed_buffers(), - host_start, nlocal,fix); - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - hbnni(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnni(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } else { - hbnni(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnni(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } -} - -template -void Neighbor::hbnni(const int offload, NeighList *list, void *buffers_in, - const int astart, const int aend, void *fix_in) { - IntelBuffers *buffers = (IntelBuffers *)buffers_in; - FixIntel *fix = (FixIntel *)fix_in; - const int nall = atom->nlocal + atom->nghost; - int pad = 1; - - if (offload) { - fix->start_watch(TIME_PACK); - buffers->grow(nall, atom->nlocal, comm->nthreads, aend); - buffers->grow_nbor(list, atom->nlocal, comm->nthreads, aend); - - ATOM_T biga; - biga.x = INTEL_BIGP; - biga.y = INTEL_BIGP; - biga.z = INTEL_BIGP; - biga.w = 1; - buffers->get_x()[nall] = biga; - - const int nthreads = comm->nthreads; - #if defined(_OPENMP) - #pragma omp parallel default(none) shared(buffers) - #endif - { - int ifrom, ito, tid; - IP_PRE_omp_range_id_align(ifrom, ito, tid, nall, nthreads, - sizeof(ATOM_T)); - buffers->thr_pack(ifrom, ito, 0); - } - fix->stop_watch(TIME_PACK); - - fix->start_watch(TIME_HOST_NEIGHBOR); - bin_atoms(buffers->get_x(), buffers->get_atombin(), - buffers->get_binpacked()); - if (INTEL_MIC_NBOR_PAD > 1) - pad = INTEL_MIC_NBOR_PAD * sizeof(float) / sizeof(flt_t); - } else { - fix->start_watch(TIME_HOST_NEIGHBOR); - if (INTEL_NBOR_PAD > 1) - pad = INTEL_NBOR_PAD * sizeof(float) / sizeof(flt_t); - } - const int pad_width = pad; - - if (aend-astart == 0) { - fix->stop_watch(TIME_HOST_NEIGHBOR); - return; - } - - const ATOM_T * _noalias const x = buffers->get_x(); - int * _noalias const firstneigh = buffers->firstneigh(list); - - const int molecular = atom->molecular; - int *ns = NULL; - tagint *s = NULL; - int tag_size = 0, special_size; - if (buffers->need_tag()) tag_size = nall; - if (molecular) { - s = atom->special[0]; - ns = atom->nspecial[0]; - special_size = aend; - } else { - s = &buffers->_special_holder; - ns = &buffers->_nspecial_holder; - special_size = 0; - } - const tagint * _noalias const special = s; - const int * _noalias const nspecial = ns; - const int maxspecial = atom->maxspecial; - const tagint * _noalias const tag = atom->tag; - - int * _noalias const ilist = list->ilist; - int * _noalias numneigh = list->numneigh; - int * _noalias const cnumneigh = buffers->cnumneigh(list); - const int nstencil = list->nstencil; - const int * _noalias const stencil = list->stencil; - const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; - const int ntypes = atom->ntypes + 1; - const int nlocal = atom->nlocal; - - #ifndef _LMP_INTEL_OFFLOAD - int * const mask = atom->mask; - tagint * const molecule = atom->molecule; - #endif - - int tnum; - int *overflow; - double *timer_compute; - if (offload) { - timer_compute = fix->off_watch_neighbor(); - tnum = buffers->get_off_threads(); - overflow = fix->get_off_overflow_flag(); - fix->stop_watch(TIME_HOST_NEIGHBOR); - fix->start_watch(TIME_OFFLOAD_LATENCY); - } else { - tnum = comm->nthreads; - overflow = fix->get_overflow_flag(); - } - const int nthreads = tnum; - const int maxnbors = buffers->get_max_nbors(); - int * _noalias const atombin = buffers->get_atombin(); - const int * _noalias const binpacked = buffers->get_binpacked(); - - const int xperiodic = domain->xperiodic; - const int yperiodic = domain->yperiodic; - const int zperiodic = domain->zperiodic; - const flt_t xprd_half = domain->xprd_half; - const flt_t yprd_half = domain->yprd_half; - const flt_t zprd_half = domain->zprd_half; - - // Make sure dummy coordinates to eliminate loop remainder not within cutoff - { - const flt_t dx = (INTEL_BIGP - bboxhi[0]); - const flt_t dy = (INTEL_BIGP - bboxhi[1]); - const flt_t dz = (INTEL_BIGP - bboxhi[2]); - if (dx * dx + dy * dy + dz * dz < static_cast(cutneighmaxsq)) - error->one(FLERR, - "Intel package expects no atoms within cutoff of {1e15,1e15,1e15}."); - } - - #ifdef _LMP_INTEL_OFFLOAD - const int * _noalias const binhead = this->binhead; - const int * _noalias const bins = this->bins; - const int cop = fix->coprocessor_number(); - const int separate_buffers = fix->separate_buffers(); - #pragma offload target(mic:cop) if(offload) \ - in(x:length(nall+1) alloc_if(0) free_if(0)) \ - in(tag:length(tag_size) alloc_if(0) free_if(0)) \ - in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ - in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ - in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ - in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ - in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ - in(firstneigh:length(0) alloc_if(0) free_if(0)) \ - in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ - out(numneigh:length(0) alloc_if(0) free_if(0)) \ - in(ilist:length(0) alloc_if(0) free_if(0)) \ - in(atombin:length(aend) alloc_if(0) free_if(0)) \ - in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ - in(maxnbors,nthreads,maxspecial,nstencil,pad_width,offload,nall) \ - in(separate_buffers, astart, aend, nlocal, molecular, ntypes) \ - in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ - out(overflow:length(5) alloc_if(0) free_if(0)) \ - out(timer_compute:length(1) alloc_if(0) free_if(0)) \ - signal(tag) - #endif - { - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime(); - #endif - - #ifdef _LMP_INTEL_OFFLOAD - overflow[LMP_LOCAL_MIN] = astart; - overflow[LMP_LOCAL_MAX] = aend - 1; - overflow[LMP_GHOST_MIN] = nall; - overflow[LMP_GHOST_MAX] = -1; - #endif - - int nstencilp = 0; - int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; - for (int k = 0; k < nstencil; k++) { - binstart[nstencilp] = stencil[k]; - int end = stencil[k] + 1; - for (int kk = k + 1; kk < nstencil; kk++) { - if (stencil[kk-1]+1 == stencil[kk]) { - end++; - k++; - } else break; - } - binend[nstencilp] = end; - nstencilp++; - } - - #if defined(_OPENMP) - #pragma omp parallel default(none) \ - shared(numneigh, overflow, nstencilp, binstart, binend) - #endif - { - #ifdef _LMP_INTEL_OFFLOAD - int lmin = nall, lmax = -1, gmin = nall, gmax = -1; - #endif - - const int num = aend - astart; - int tid, ifrom, ito; - IP_PRE_omp_range_id(ifrom, ito, tid, num, nthreads); - ifrom += astart; - ito += astart; - - int which; - - const int list_size = (ito + tid + 1) * maxnbors; - int ct = (ifrom + tid) * maxnbors; - int *neighptr = firstneigh + ct; - - for (int i = ifrom; i < ito; i++) { - int j, k, n, n2, itype, jtype, ibin; - double xtmp, ytmp, ztmp, delx, dely, delz, rsq; - - n = 0; - n2 = maxnbors; - - xtmp = x[i].x; - ytmp = x[i].y; - ztmp = x[i].z; - itype = x[i].w; - const int ioffset = ntypes*itype; - - // 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 = atombin[i]; - - for (k = 0; k < nstencilp; k++) { - const int bstart = binhead[ibin + binstart[k]]; - const int bend = binhead[ibin + binend[k]]; - for (int jj = bstart; jj < bend; jj++) { - const int j = binpacked[jj]; - if (j <= i) continue; - - jtype = x[j].w; - #ifndef _LMP_INTEL_OFFLOAD - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - #endif - - delx = xtmp - x[j].x; - dely = ytmp - x[j].y; - delz = ztmp - x[j].z; - rsq = delx * delx + dely * dely + delz * delz; - if (rsq <= cutneighsq[ioffset + jtype]) { - if (j < nlocal) { - if (need_ic) { - int no_special; - ominimum_image_check(no_special, delx, dely, delz); - if (no_special) - neighptr[n++] = -j - 1; - else - neighptr[n++] = j; - } else - neighptr[n++] = j; - #ifdef _LMP_INTEL_OFFLOAD - if (j < lmin) lmin = j; - if (j > lmax) lmax = j; - #endif - } else { - if (need_ic) { - int no_special; - ominimum_image_check(no_special, delx, dely, delz); - if (no_special) - neighptr[n2++] = -j - 1; - else - neighptr[n2++] = j; - } else - neighptr[n2++] = j; - #ifdef _LMP_INTEL_OFFLOAD - if (j < gmin) gmin = j; - if (j > gmax) gmax = j; - #endif - } - } - } - } - ilist[i] = i; - - cnumneigh[i] = ct; - if (n > maxnbors) *overflow = 1; - for (k = maxnbors; k < n2; k++) neighptr[n++] = neighptr[k]; - - const int edge = (n % pad_width); - if (edge) { - const int pad_end = n + (pad_width - edge); - #if defined(LMP_SIMD_COMPILER) - #pragma loop_count min=1, max=15, avg=8 - #endif - for ( ; n < pad_end; n++) - neighptr[n] = nall; - } - numneigh[i] = n; - while((n % (INTEL_DATA_ALIGN / sizeof(int))) != 0) n++; - ct += n; - neighptr += n; - if (ct + n + maxnbors > list_size) { - *overflow = 1; - ct = (ifrom + tid) * maxnbors; - } - } - - if (*overflow == 1) - for (int i = ifrom; i < ito; i++) - numneigh[i] = 0; - - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - #if defined(_OPENMP) - #pragma omp critical - #endif - { - if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; - if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; - if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; - if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; - } - #pragma omp barrier - } - - int ghost_offset = 0, nall_offset = nall; - if (separate_buffers) { - int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; - if (nghost < 0) nghost = 0; - if (offload) { - ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; - nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; - } else { - ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; - nall_offset = nlocal + nghost; - } - } - #endif - - if (molecular) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - for (int jj = 0; jj < jnum; jj++) { - const int j = jlist[jj]; - if (need_ic && j < 0) { - which = 0; - jlist[jj] = -j - 1; - } else - ofind_special(which, special, nspecial, i, tag[j]); - #ifdef _LMP_INTEL_OFFLOAD - if (j >= nlocal) { - if (j == nall) - jlist[jj] = nall_offset; - else if (which) - jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); - else jlist[jj]-=ghost_offset; - } else - #endif - if (which) jlist[jj] = j ^ (which << SBBITS); - } - } - } - #ifdef _LMP_INTEL_OFFLOAD - else if (separate_buffers) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - int jj = 0; - for (jj = 0; jj < jnum; jj++) - if (jlist[jj] >= nlocal) break; - while (jj < jnum) { - if (jlist[jj] == nall) jlist[jj] = nall_offset; - else jlist[jj] -= ghost_offset; - jj++; - } - } - } - #endif - } // end omp - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime() - *timer_compute; - #endif - } // end offload - - if (offload) { - fix->stop_watch(TIME_OFFLOAD_LATENCY); - #ifdef _LMP_INTEL_OFFLOAD - for (int n = 0; n < aend; n++) { - ilist[n] = n; - numneigh[n] = 0; - } - #endif - } else { - for (int i = astart; i < aend; i++) - list->firstneigh[i] = firstneigh + cnumneigh[i]; - fix->stop_watch(TIME_HOST_NEIGHBOR); - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - fix->start_watch(TIME_PACK); - fix->set_neighbor_host_sizes(); - buffers->pack_sep_from_single(fix->host_min_local(), - fix->host_used_local(), - fix->host_min_ghost(), - fix->host_used_ghost()); - fix->stop_watch(TIME_PACK); - } - #endif - } -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_newton_intel(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - list->inum = nlocal; - - // Get fix for intel stuff - FixIntel *fix = static_cast(fix_intel); - - const int off_end = fix->offload_end_neighbor(); - int host_start = fix->host_start_neighbor();; - int offload_noghost = 0; - #ifdef _LMP_INTEL_OFFLOAD - if (fix->full_host_list()) host_start = 0; - offload_noghost = fix->offload_noghost(); - if (exclude) - error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); - #endif - if (list->nstencil / 2 > INTEL_MAX_STENCIL_CHECK) - error->all(FLERR, "Too many neighbor bins for USER-INTEL package."); - - int need_ic = 0; - if (atom->molecular) - dminimum_image_check(need_ic, cutneighmax, cutneighmax, cutneighmax); - - if (need_ic) { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix); - } - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } else { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix); - } - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } -} - -template -void Neighbor::hbni(const int offload, NeighList *list, void *buffers_in, - const int astart, const int aend, void *fix_in, - const int offload_end) { - IntelBuffers *buffers = (IntelBuffers *)buffers_in; - FixIntel *fix = (FixIntel *)fix_in; - const int nall = atom->nlocal + atom->nghost; - int pad = 1; - - if (offload) { - fix->start_watch(TIME_PACK); - buffers->grow(nall, atom->nlocal, comm->nthreads, aend); - buffers->grow_nbor(list, atom->nlocal, comm->nthreads, aend); - - ATOM_T biga; - biga.x = INTEL_BIGP; - biga.y = INTEL_BIGP; - biga.z = INTEL_BIGP; - biga.w = 1; - buffers->get_x()[nall]=biga; - - const int nthreads = comm->nthreads; - #if defined(_OPENMP) - #pragma omp parallel default(none) shared(buffers) - #endif - { - int ifrom, ito, tid; - IP_PRE_omp_range_id_align(ifrom, ito, tid, nall, nthreads, - sizeof(ATOM_T)); - buffers->thr_pack(ifrom, ito, 0); - } - fix->stop_watch(TIME_PACK); - - fix->start_watch(TIME_HOST_NEIGHBOR); - bin_atoms(buffers->get_x(), buffers->get_atombin(), - buffers->get_binpacked()); - if (INTEL_MIC_NBOR_PAD > 1) - pad = INTEL_MIC_NBOR_PAD * sizeof(float) / sizeof(flt_t); - } else { - fix->start_watch(TIME_HOST_NEIGHBOR); - if (INTEL_NBOR_PAD > 1) - pad = INTEL_NBOR_PAD * sizeof(float) / sizeof(flt_t); - } - const int pad_width = pad; - - if (aend-astart == 0) { - fix->stop_watch(TIME_HOST_NEIGHBOR); - return; - } - - const ATOM_T * _noalias const x = buffers->get_x(); - int * _noalias const firstneigh = buffers->firstneigh(list); - int nall_t = nall; - if (offload_noghost && offload) nall_t = atom->nlocal; - const int e_nall = nall_t; - - const int molecular = atom->molecular; - int *ns = NULL; - tagint *s = NULL; - int tag_size = 0, special_size; - if (buffers->need_tag()) tag_size = e_nall; - if (molecular) { - s = atom->special[0]; - ns = atom->nspecial[0]; - special_size = aend; - } else { - s = &buffers->_special_holder; - ns = &buffers->_nspecial_holder; - special_size = 0; - } - const tagint * _noalias const special = s; - const int * _noalias const nspecial = ns; - const int maxspecial = atom->maxspecial; - const tagint * _noalias const tag = atom->tag; - - int * _noalias const ilist = list->ilist; - int * _noalias numneigh = list->numneigh; - int * _noalias const cnumneigh = buffers->cnumneigh(list); - const int nstencil = list->nstencil; - const int * _noalias const stencil = list->stencil; - const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; - const int ntypes = atom->ntypes + 1; - const int nlocal = atom->nlocal; - - #ifndef _LMP_INTEL_OFFLOAD - int * const mask = atom->mask; - tagint * const molecule = atom->molecule; - #endif - - int tnum; - int *overflow; - double *timer_compute; - if (offload) { - timer_compute = fix->off_watch_neighbor(); - tnum = buffers->get_off_threads(); - overflow = fix->get_off_overflow_flag(); - fix->stop_watch(TIME_HOST_NEIGHBOR); - fix->start_watch(TIME_OFFLOAD_LATENCY); - } else { - tnum = comm->nthreads; - overflow = fix->get_overflow_flag(); - } - const int nthreads = tnum; - const int maxnbors = buffers->get_max_nbors(); - int * _noalias const atombin = buffers->get_atombin(); - const int * _noalias const binpacked = buffers->get_binpacked(); - - const int xperiodic = domain->xperiodic; - const int yperiodic = domain->yperiodic; - const int zperiodic = domain->zperiodic; - const flt_t xprd_half = domain->xprd_half; - const flt_t yprd_half = domain->yprd_half; - const flt_t zprd_half = domain->zprd_half; - - // Make sure dummy coordinates to eliminate loop remainder not within cutoff - { - const flt_t dx = (INTEL_BIGP - bboxhi[0]); - const flt_t dy = (INTEL_BIGP - bboxhi[1]); - const flt_t dz = (INTEL_BIGP - bboxhi[2]); - if (dx * dx + dy * dy + dz * dz < static_cast(cutneighmaxsq)) - error->one(FLERR, - "Intel package expects no atoms within cutoff of {1e15,1e15,1e15}."); - } - - #ifdef _LMP_INTEL_OFFLOAD - const int * _noalias const binhead = this->binhead; - const int * _noalias const bins = this->bins; - const int cop = fix->coprocessor_number(); - const int separate_buffers = fix->separate_buffers(); - #pragma offload target(mic:cop) if(offload) \ - in(x:length(e_nall+1) alloc_if(0) free_if(0)) \ - in(tag:length(tag_size) alloc_if(0) free_if(0)) \ - in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ - in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ - in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ - in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ - in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ - in(firstneigh:length(0) alloc_if(0) free_if(0)) \ - in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ - out(numneigh:length(0) alloc_if(0) free_if(0)) \ - in(ilist:length(0) alloc_if(0) free_if(0)) \ - in(atombin:length(aend) alloc_if(0) free_if(0)) \ - in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ - in(maxnbors,nthreads,maxspecial,nstencil,e_nall,offload,pad_width) \ - in(offload_end,separate_buffers,astart, aend, nlocal, molecular, ntypes) \ - in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ - out(overflow:length(5) alloc_if(0) free_if(0)) \ - out(timer_compute:length(1) alloc_if(0) free_if(0)) \ - signal(tag) - #endif - { - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime(); - #endif - - #ifdef _LMP_INTEL_OFFLOAD - overflow[LMP_LOCAL_MIN] = astart; - overflow[LMP_LOCAL_MAX] = aend - 1; - overflow[LMP_GHOST_MIN] = e_nall; - overflow[LMP_GHOST_MAX] = -1; - #endif - - int nstencilp = 0; - int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; - for (int k = 0; k < nstencil; k++) { - binstart[nstencilp] = stencil[k]; - int end = stencil[k] + 1; - for (int kk = k + 1; kk < nstencil; kk++) { - if (stencil[kk-1]+1 == stencil[kk]) { - end++; - k++; - } else break; - } - binend[nstencilp] = end; - nstencilp++; - } - - #if defined(_OPENMP) - #pragma omp parallel default(none) \ - shared(numneigh, overflow, nstencilp, binstart, binend) - #endif - { - #ifdef _LMP_INTEL_OFFLOAD - int lmin = e_nall, lmax = -1, gmin = e_nall, gmax = -1; - #endif - - const int num = aend - astart; - int tid, ifrom, ito; - - #ifdef OUTER_CHUNK - const int swidth = ip_simd::SIMD_type::width(); - IP_PRE_omp_range_id_vec(ifrom, ito, tid, num, nthreads, swidth); - ifrom += astart; - ito += astart; - int e_ito = ito; - if (ito == num) { - int imod = ito % swidth; - if (imod) e_ito += swidth - imod; - } - const int list_size = (e_ito + tid * 2 + 2) * maxnbors; - #else - const int swidth = 1; - IP_PRE_omp_range_id(ifrom, ito, tid, num, nthreads); - ifrom += astart; - ito += astart; - const int list_size = (ito + tid * 2 + 2) * maxnbors; - #endif - - int which; - - int pack_offset = maxnbors * swidth; - int ct = (ifrom + tid * 2) * maxnbors; - int *neighptr = firstneigh + ct; - const int obound = pack_offset + maxnbors * 2; - - int max_chunk = 0; - int lane = 0; - for (int i = ifrom; i < ito; i++) { - const flt_t xtmp = x[i].x; - const flt_t ytmp = x[i].y; - const flt_t ztmp = x[i].z; - const int itype = x[i].w; - const int ioffset = ntypes * itype; - - // 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/to the right" of i - - int raw_count = pack_offset; - for (int j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost && offload) continue; - #endif - if (x[j].z < ztmp) continue; - if (x[j].z == ztmp) { - if (x[j].y < ytmp) continue; - if (x[j].y == ytmp && x[j].x < xtmp) continue; - } - } - #ifdef _LMP_INTEL_OFFLOAD - else if (offload_noghost && i < offload_end) continue; - #endif - - #ifndef _LMP_INTEL_OFFLOAD - if (exclude) { - const int jtype = x[j].w; - if (exclusion(i,j,itype,jtype,mask,molecule)) continue; - } - #endif - - neighptr[raw_count++] = j; - } - - // loop over all atoms in other bins in stencil, store every pair - - const int ibin = atombin[i]; - if (exclude) { - for (int k = 0; k < nstencilp; k++) { - const int bstart = binhead[ibin + binstart[k]]; - const int bend = binhead[ibin + binend[k]]; - #ifndef _LMP_INTEL_OFFLOAD - #ifdef INTEL_VMASK - #pragma simd - #endif - #endif - for (int jj = bstart; jj < bend; jj++) { - const int j = binpacked[jj]; - - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - if (j < nlocal) { - if (i < offload_end) continue; - } else if (offload) continue; - } - #endif - - #ifndef _LMP_INTEL_OFFLOAD - const int jtype = x[j].w; - if (exclusion(i,j,itype,jtype,mask,molecule)) continue; - #endif - - neighptr[raw_count++] = j; - } - } - } else { - for (int k = 0; k < nstencilp; k++) { - const int bstart = binhead[ibin + binstart[k]]; - const int bend = binhead[ibin + binend[k]]; - #ifndef _LMP_INTEL_OFFLOAD - #ifdef INTEL_VMASK - #pragma simd - #endif - #endif - for (int jj = bstart; jj < bend; jj++) { - const int j = binpacked[jj]; - - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - if (j < nlocal) { - if (i < offload_end) continue; - } else if (offload) continue; - } - #endif - - neighptr[raw_count++] = j; - } - } - } - - if (raw_count > obound) *overflow = 1; - - #if defined(LMP_SIMD_COMPILER) - #ifdef _LMP_INTEL_OFFLOAD - int vlmin = lmin, vlmax = lmax, vgmin = gmin, vgmax = gmax; - #if __INTEL_COMPILER+0 > 1499 - #pragma vector aligned - #pragma simd reduction(max:vlmax,vgmax) reduction(min:vlmin, vgmin) - #endif - #else - #pragma vector aligned - #pragma simd - #endif - #endif - for (int u = pack_offset; u < raw_count; u++) { - int j = neighptr[u]; - 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 int jtype = x[j].w; - const flt_t rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutneighsq[ioffset + jtype]) - neighptr[u] = e_nall; - else { - if (need_ic) { - int no_special; - ominimum_image_check(no_special, delx, dely, delz); - if (no_special) - neighptr[u] = -j - 1; - } - #ifdef _LMP_INTEL_OFFLOAD - if (j < nlocal) { - if (j < vlmin) vlmin = j; - if (j > vlmax) vlmax = j; - } else { - if (j < vgmin) vgmin = j; - if (j > vgmax) vgmax = j; - } - #endif - } - } - #ifdef _LMP_INTEL_OFFLOAD - lmin = MIN(lmin,vlmin); - gmin = MIN(gmin,vgmin); - lmax = MAX(lmax,vlmax); - gmax = MAX(gmax,vgmax); - #endif - - int n = lane, n2 = pack_offset; - for (int u = pack_offset; u < raw_count; u++) { - const int j = neighptr[u]; - int pj = j; - if (pj < e_nall) { - if (need_ic) - if (pj < 0) pj = -pj - 1; - - if (pj < nlocal) { - neighptr[n] = j; - n += swidth; - } else - neighptr[n2++] = j; - } - } - int ns = (n - lane) / swidth; - for (int u = pack_offset; u < n2; u++) { - neighptr[n] = neighptr[u]; - n += swidth; - } - - ilist[i] = i; - cnumneigh[i] = ct + lane; - ns += n2 - pack_offset; - #ifndef OUTER_CHUNK - int edge = (ns % pad_width); - if (edge) { - const int pad_end = ns + (pad_width - edge); - #if defined(LMP_SIMD_COMPILER) - #pragma loop_count min=1, max=15, avg=8 - #endif - for ( ; ns < pad_end; ns++) - neighptr[ns] = e_nall; - } - #endif - numneigh[i] = ns; - - #ifdef OUTER_CHUNK - if (ns > max_chunk) max_chunk = ns; - lane++; - if (lane == swidth) { - ct += max_chunk * swidth; - const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); - int edge = (ct % alignb); - if (edge) ct += alignb - edge; - neighptr = firstneigh + ct; - max_chunk = 0; - pack_offset = maxnbors * swidth; - lane = 0; - if (ct + obound > list_size) { - if (i < ito - 1) { - *overflow = 1; - ct = (ifrom + tid * 2) * maxnbors; - } - } - } - #else - ct += ns; - const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); - edge = (ct % alignb); - if (edge) ct += alignb - edge; - neighptr = firstneigh + ct; - if (ct + obound > list_size) { - if (i < ito - 1) { - *overflow = 1; - ct = (ifrom + tid * 2) * maxnbors; - } - } - #endif - } - - if (*overflow == 1) - for (int i = ifrom; i < ito; i++) - numneigh[i] = 0; - - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - #if defined(_OPENMP) - #pragma omp critical - #endif - { - if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; - if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; - if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; - if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; - } - #pragma omp barrier - } - - int ghost_offset = 0, nall_offset = e_nall; - if (separate_buffers) { - int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; - if (nghost < 0) nghost = 0; - if (offload) { - ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; - nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; - } else { - ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; - nall_offset = nlocal + nghost; - } - } - #endif - - if (molecular) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - #ifndef OUTER_CHUNK - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma simd - #endif - for (int jj = 0; jj < jnum; jj++) { - #else - const int trip = jnum * swidth; - for (int jj = 0; jj < trip; jj+= swidth) { - #endif - const int j = jlist[jj]; - if (need_ic && j < 0) { - which = 0; - jlist[jj] = -j - 1; - } else - ofind_special(which, special, nspecial, i, tag[j]); - #ifdef _LMP_INTEL_OFFLOAD - if (j >= nlocal) { - if (j == e_nall) - jlist[jj] = nall_offset; - else if (which) - jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); - else jlist[jj]-=ghost_offset; - } else - #endif - if (which) jlist[jj] = j ^ (which << SBBITS); - } - } - } - #ifdef _LMP_INTEL_OFFLOAD - else if (separate_buffers) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - int jj = 0; - for (jj = 0; jj < jnum; jj++) - if (jlist[jj] >= nlocal) break; - while (jj < jnum) { - if (jlist[jj] == e_nall) jlist[jj] = nall_offset; - else jlist[jj] -= ghost_offset; - jj++; - } - } - } - #endif - } // end omp - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime() - *timer_compute; - #endif - } // end offload - - if (offload) { - fix->stop_watch(TIME_OFFLOAD_LATENCY); - #ifdef _LMP_INTEL_OFFLOAD - for (int n = 0; n < aend; n++) { - ilist[n] = n; - numneigh[n] = 0; - } - #endif - } else { - for (int i = astart; i < aend; i++) - list->firstneigh[i] = firstneigh + cnumneigh[i]; - fix->stop_watch(TIME_HOST_NEIGHBOR); - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - fix->start_watch(TIME_PACK); - fix->set_neighbor_host_sizes(); - buffers->pack_sep_from_single(fix->host_min_local(), - fix->host_used_local(), - fix->host_min_ghost(), - fix->host_used_ghost()); - fix->stop_watch(TIME_PACK); - } - #endif - } -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_newton_tri_intel(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - list->inum = nlocal; - - // Get fix for intel stuff - FixIntel *fix = static_cast(fix_intel); - - const int off_end = fix->offload_end_neighbor(); - int host_start = fix->host_start_neighbor(); - int offload_noghost = 0; - #ifdef _LMP_INTEL_OFFLOAD - if (fix->full_host_list()) host_start = 0; - offload_noghost = fix->offload_noghost(); - if (exclude) - error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); - #endif - if (list->nstencil / 2 > INTEL_MAX_STENCIL_CHECK) - error->all(FLERR, "Too many neighbor bins for USER-INTEL package."); - - int need_ic = 0; - if (atom->molecular) - dminimum_image_check(need_ic, cutneighmax, cutneighmax, cutneighmax); - - if (need_ic) { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix); - } - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } else { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix); - } - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } -} - -template -void Neighbor::hbnti(const int offload, NeighList *list, void *buffers_in, - const int astart, const int aend, void *fix_in, - const int offload_end) { - IntelBuffers *buffers = (IntelBuffers *)buffers_in; - FixIntel *fix = (FixIntel *)fix_in; - const int nall = atom->nlocal + atom->nghost; - int pad = 1; - if (list->nstencil > INTEL_MAX_STENCIL) - error->all(FLERR, "Too many neighbor bins for USER-INTEL package."); - - if (offload) { - fix->start_watch(TIME_PACK); - buffers->grow(nall, atom->nlocal, comm->nthreads, aend); - buffers->grow_nbor(list, atom->nlocal, comm->nthreads, aend); - - ATOM_T biga; - biga.x = INTEL_BIGP; - biga.y = INTEL_BIGP; - biga.z = INTEL_BIGP; - biga.w = 1; - buffers->get_x()[nall]=biga; - - const int nthreads = comm->nthreads; - #if defined(_OPENMP) - #pragma omp parallel default(none) shared(buffers) - #endif - { - int ifrom, ito, tid; - IP_PRE_omp_range_id_align(ifrom, ito, tid, nall, nthreads, - sizeof(ATOM_T)); - buffers->thr_pack(ifrom, ito, 0); - } - fix->stop_watch(TIME_PACK); - - fix->start_watch(TIME_HOST_NEIGHBOR); - bin_atoms(buffers->get_x(), buffers->get_atombin(), - buffers->get_binpacked()); - if (INTEL_MIC_NBOR_PAD > 1) - pad = INTEL_MIC_NBOR_PAD * sizeof(float) / sizeof(flt_t); - } else { - fix->start_watch(TIME_HOST_NEIGHBOR); - if (INTEL_NBOR_PAD > 1) - pad = INTEL_NBOR_PAD * sizeof(float) / sizeof(flt_t); - } - const int pad_width = pad; - - if (aend-astart == 0) { - fix->stop_watch(TIME_HOST_NEIGHBOR); - return; - } - - const ATOM_T * _noalias const x = buffers->get_x(); - int * _noalias const firstneigh = buffers->firstneigh(list); - int nall_t = nall; - if (offload_noghost && offload) nall_t = atom->nlocal; - const int e_nall = nall_t; - - const int molecular = atom->molecular; - int *ns = NULL; - tagint *s = NULL; - int tag_size = 0, special_size; - if (buffers->need_tag()) tag_size = e_nall; - if (molecular) { - s = atom->special[0]; - ns = atom->nspecial[0]; - special_size = aend; - } else { - s = &buffers->_special_holder; - ns = &buffers->_nspecial_holder; - special_size = 0; - } - const tagint * _noalias const special = s; - const int * _noalias const nspecial = ns; - const int maxspecial = atom->maxspecial; - const tagint * _noalias const tag = atom->tag; - - int * _noalias const ilist = list->ilist; - int * _noalias numneigh = list->numneigh; - int * _noalias const cnumneigh = buffers->cnumneigh(list); - const int nstencil = list->nstencil; - const int * _noalias const stencil = list->stencil; - const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; - const int ntypes = atom->ntypes + 1; - const int nlocal = atom->nlocal; - - #ifndef _LMP_INTEL_OFFLOAD - int * const mask = atom->mask; - tagint * const molecule = atom->molecule; - #endif - - int tnum; - int *overflow; - double *timer_compute; - if (offload) { - timer_compute = fix->off_watch_neighbor(); - tnum = buffers->get_off_threads(); - overflow = fix->get_off_overflow_flag(); - fix->stop_watch(TIME_HOST_NEIGHBOR); - fix->start_watch(TIME_OFFLOAD_LATENCY); - } else { - tnum = comm->nthreads; - overflow = fix->get_overflow_flag(); - } - const int nthreads = tnum; - const int maxnbors = buffers->get_max_nbors(); - int * _noalias const atombin = buffers->get_atombin(); - const int * _noalias const binpacked = buffers->get_binpacked(); - - const int xperiodic = domain->xperiodic; - const int yperiodic = domain->yperiodic; - const int zperiodic = domain->zperiodic; - const flt_t xprd_half = domain->xprd_half; - const flt_t yprd_half = domain->yprd_half; - const flt_t zprd_half = domain->zprd_half; - - // Make sure dummy coordinates to eliminate loop remainder not within cutoff - { - const flt_t dx = (INTEL_BIGP - bboxhi[0]); - const flt_t dy = (INTEL_BIGP - bboxhi[1]); - const flt_t dz = (INTEL_BIGP - bboxhi[2]); - if (dx * dx + dy * dy + dz * dz < static_cast(cutneighmaxsq)) - error->one(FLERR, - "Intel package expects no atoms within cutoff of {1e15,1e15,1e15}."); - } - - #ifdef _LMP_INTEL_OFFLOAD - const int * _noalias const binhead = this->binhead; - const int * _noalias const bins = this->bins; - const int cop = fix->coprocessor_number(); - const int separate_buffers = fix->separate_buffers(); - #pragma offload target(mic:cop) if(offload) \ - in(x:length(e_nall+1) alloc_if(0) free_if(0)) \ - in(tag:length(tag_size) alloc_if(0) free_if(0)) \ - in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ - in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ - in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ - in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ - in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ - in(firstneigh:length(0) alloc_if(0) free_if(0)) \ - in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ - out(numneigh:length(0) alloc_if(0) free_if(0)) \ - in(ilist:length(0) alloc_if(0) free_if(0)) \ - in(atombin:length(aend) alloc_if(0) free_if(0)) \ - in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ - in(maxnbors,nthreads,maxspecial,nstencil,offload_end,pad_width,e_nall) \ - in(offload,separate_buffers, astart, aend, nlocal, molecular, ntypes) \ - in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ - out(overflow:length(5) alloc_if(0) free_if(0)) \ - out(timer_compute:length(1) alloc_if(0) free_if(0)) \ - signal(tag) - #endif - { - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime(); - #endif - - #ifdef _LMP_INTEL_OFFLOAD - overflow[LMP_LOCAL_MIN] = astart; - overflow[LMP_LOCAL_MAX] = aend - 1; - overflow[LMP_GHOST_MIN] = e_nall; - overflow[LMP_GHOST_MAX] = -1; - #endif - - int nstencilp = 0; - int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; - for (int k = 0; k < nstencil; k++) { - binstart[nstencilp] = stencil[k]; - int end = stencil[k] + 1; - for (int kk = k + 1; kk < nstencil; kk++) { - if (stencil[kk-1]+1 == stencil[kk]) { - end++; - k++; - } else break; - } - binend[nstencilp] = end; - nstencilp++; - } - - #if defined(_OPENMP) - #pragma omp parallel default(none) \ - shared(numneigh, overflow, nstencilp, binstart, binend) - #endif - { - #ifdef _LMP_INTEL_OFFLOAD - int lmin = e_nall, lmax = -1, gmin = e_nall, gmax = -1; - #endif - - const int num = aend - astart; - int tid, ifrom, ito; - IP_PRE_omp_range_id(ifrom, ito, tid, num, nthreads); - ifrom += astart; - ito += astart; - - int which; - - const int list_size = (ito + tid * 2 + 2) * maxnbors; - int ct = (ifrom + tid * 2) * maxnbors; - int *neighptr = firstneigh + ct; - const int obound = maxnbors * 3; - - for (int i = ifrom; i < ito; i++) { - const flt_t xtmp = x[i].x; - const flt_t ytmp = x[i].y; - const flt_t ztmp = x[i].z; - const int itype = x[i].w; - const int ioffset = ntypes * itype; - - // loop over all atoms in bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - const int ibin = atombin[i]; - - int raw_count = maxnbors; - for (int k = 0; k < nstencilp; k++) { - const int bstart = binhead[ibin + binstart[k]]; - const int bend = binhead[ibin + binend[k]]; - for (int jj = bstart; jj < bend; jj++) { - const int j = binpacked[jj]; - - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - if (j < nlocal) { - if (i < offload_end) continue; - } else if (offload) continue; - } - #endif - - if (x[j].z < ztmp) continue; - if (x[j].z == ztmp) { - if (x[j].y < ytmp) continue; - if (x[j].y == ytmp) { - if (x[j].x < xtmp) continue; - if (x[j].x == xtmp && j <= i) continue; - } - } - - #ifndef _LMP_INTEL_OFFLOAD - if (exclude) { - const int jtype = x[j].w; - if (exclusion(i,j,itype,jtype,mask,molecule)) continue; - } - #endif - - neighptr[raw_count++] = j; - } - } - if (raw_count > obound) - *overflow = 1; - - #if defined(LMP_SIMD_COMPILER) - #ifdef _LMP_INTEL_OFFLOAD - int vlmin = lmin, vlmax = lmax, vgmin = gmin, vgmax = gmax; - #if __INTEL_COMPILER+0 > 1499 - #pragma vector aligned - #pragma simd reduction(max:vlmax,vgmax) reduction(min:vlmin, vgmin) - #endif - #else - #pragma vector aligned - #pragma simd - #endif - #endif - for (int u = maxnbors; u < raw_count; u++) { - int j = neighptr[u]; - 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 int jtype = x[j].w; - const flt_t rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutneighsq[ioffset + jtype]) - neighptr[u] = e_nall; - else { - if (need_ic) { - int no_special; - ominimum_image_check(no_special, delx, dely, delz); - if (no_special) - neighptr[u] = -j - 1; - } - - #ifdef _LMP_INTEL_OFFLOAD - if (j < nlocal) { - if (j < vlmin) vlmin = j; - if (j > vlmax) vlmax = j; - } else { - if (j < vgmin) vgmin = j; - if (j > vgmax) vgmax = j; - } - #endif - } - } - - int n = 0, n2 = maxnbors; - for (int u = maxnbors; u < raw_count; u++) { - const int j = neighptr[u]; - int pj = j; - if (pj < e_nall) { - if (need_ic) - if (pj < 0) pj = -pj - 1; - - if (pj < nlocal) - neighptr[n++] = j; - else - neighptr[n2++] = j; - } - } - int ns = n; - for (int u = maxnbors; u < n2; u++) - neighptr[n++] = neighptr[u]; - - ilist[i] = i; - cnumneigh[i] = ct; - ns += n2 - maxnbors; - - int edge = (ns % pad_width); - if (edge) { - const int pad_end = ns + (pad_width - edge); - #if defined(LMP_SIMD_COMPILER) - #pragma loop_count min=1, max=15, avg=8 - #endif - for ( ; ns < pad_end; ns++) - neighptr[ns] = e_nall; - } - numneigh[i] = ns; - - ct += ns; - const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); - edge = (ct % alignb); - if (edge) ct += alignb - edge; - neighptr = firstneigh + ct; - if (ct + obound > list_size) { - if (i < ito - 1) { - *overflow = 1; - ct = (ifrom + tid * 2) * maxnbors; - } - } - } - - if (*overflow == 1) - for (int i = ifrom; i < ito; i++) - numneigh[i] = 0; - - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - #if defined(_OPENMP) - #pragma omp critical - #endif - { - if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; - if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; - if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; - if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; - } - #pragma omp barrier - } - - int ghost_offset = 0, nall_offset = e_nall; - if (separate_buffers) { - int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; - if (nghost < 0) nghost = 0; - if (offload) { - ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; - nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; - } else { - ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; - nall_offset = nlocal + nghost; - } - } - #endif - - if (molecular) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - #if defined(LMP_SIMD_COMPILER) - #pragma vector aligned - #pragma simd - #endif - for (int jj = 0; jj < jnum; jj++) { - const int j = jlist[jj]; - if (need_ic && j < 0) { - which = 0; - jlist[jj] = -j - 1; - } else - ofind_special(which, special, nspecial, i, tag[j]); - #ifdef _LMP_INTEL_OFFLOAD - if (j >= nlocal) { - if (j == e_nall) - jlist[jj] = nall_offset; - else if (which) - jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); - else jlist[jj]-=ghost_offset; - } else - #endif - if (which) jlist[jj] = j ^ (which << SBBITS); - } - } - } - #ifdef _LMP_INTEL_OFFLOAD - else if (separate_buffers) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - int jj = 0; - for (jj = 0; jj < jnum; jj++) - if (jlist[jj] >= nlocal) break; - while (jj < jnum) { - if (jlist[jj] == e_nall) jlist[jj] = nall_offset; - else jlist[jj] -= ghost_offset; - jj++; - } - } - } - #endif - } // end omp - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime() - *timer_compute; - #endif - } // end offload - - if (offload) { - fix->stop_watch(TIME_OFFLOAD_LATENCY); - #ifdef _LMP_INTEL_OFFLOAD - for (int n = 0; n < aend; n++) { - ilist[n] = n; - numneigh[n] = 0; - } - #endif - } else { - for (int i = astart; i < aend; i++) - list->firstneigh[i] = firstneigh + cnumneigh[i]; - fix->stop_watch(TIME_HOST_NEIGHBOR); - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - fix->start_watch(TIME_PACK); - fix->set_neighbor_host_sizes(); - buffers->pack_sep_from_single(fix->host_min_local(), - fix->host_used_local(), - fix->host_min_ghost(), - fix->host_used_ghost()); - fix->stop_watch(TIME_PACK); - } - #endif - } -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void Neighbor::full_bin_intel(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - list->inum = nlocal; - list->gnum = 0; - - // Get fix for intel stuff - FixIntel *fix = static_cast(fix_intel); - - const int off_end = fix->offload_end_neighbor(); - int host_start = fix->host_start_neighbor();; - int offload_noghost = 0; - #ifdef _LMP_INTEL_OFFLOAD - if (fix->full_host_list()) host_start = 0; - offload_noghost = fix->offload_noghost(); - if (exclude) - error->all(FLERR, "Exclusion lists not yet supported for Intel offload"); - #endif - if (list->nstencil > INTEL_MAX_STENCIL_CHECK) - error->all(FLERR, "Too many neighbor bins for USER-INTEL package."); - - int need_ic = 0; - if (atom->molecular) - dminimum_image_check(need_ic, cutneighmax, cutneighmax, cutneighmax); - - if (need_ic) { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix); - } - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } else { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix); - } - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } -} - -template -void Neighbor::fbi(const int offload, NeighList *list, void *buffers_in, - const int astart, const int aend, void *fix_in, - const int offload_end) { - IntelBuffers *buffers = (IntelBuffers *)buffers_in; - FixIntel *fix = (FixIntel *)fix_in; - const int nall = atom->nlocal + atom->nghost; - int pad = 1; - - const int pack_width = fix->nbor_pack_width(); - - if (offload) { - fix->start_watch(TIME_PACK); - buffers->grow(nall, atom->nlocal, comm->nthreads, aend); - buffers->grow_nbor(list, atom->nlocal, comm->nthreads, aend, pack_width); - - ATOM_T biga; - biga.x = INTEL_BIGP; - biga.y = INTEL_BIGP; - biga.z = INTEL_BIGP; - biga.w = 1; - buffers->get_x()[nall]=biga; - - const int nthreads = comm->nthreads; - #if defined(_OPENMP) - #pragma omp parallel default(none) shared(buffers) - #endif - { - int ifrom, ito, tid; - IP_PRE_omp_range_id_align(ifrom, ito, tid, nall, nthreads, - sizeof(ATOM_T)); - buffers->thr_pack(ifrom, ito, 0); - } - fix->stop_watch(TIME_PACK); - - fix->start_watch(TIME_HOST_NEIGHBOR); - bin_atoms(buffers->get_x(), buffers->get_atombin(), - buffers->get_binpacked()); - } else { - fix->start_watch(TIME_HOST_NEIGHBOR); - } - const int pad_width = pad; - - if (aend-astart == 0) { - fix->stop_watch(TIME_HOST_NEIGHBOR); - return; - } - - const ATOM_T * _noalias const x = buffers->get_x(); - int * _noalias const firstneigh = buffers->firstneigh(list); - int nall_t = nall; - if (offload_noghost && offload) nall_t = atom->nlocal; - const int e_nall = nall_t; - - const int molecular = atom->molecular; - int *ns = NULL; - tagint *s = NULL; - int tag_size = 0, special_size; - if (buffers->need_tag()) tag_size = e_nall; - if (molecular) { - s = atom->special[0]; - ns = atom->nspecial[0]; - special_size = aend; - } else { - s = &buffers->_special_holder; - ns = &buffers->_nspecial_holder; - special_size = 0; - } - const tagint * _noalias const special = s; - const int * _noalias const nspecial = ns; - const int maxspecial = atom->maxspecial; - const tagint * _noalias const tag = atom->tag; - - int * _noalias const ilist = list->ilist; - int * _noalias numneigh = list->numneigh; - int * _noalias const cnumneigh = buffers->cnumneigh(list); - const int nstencil = list->nstencil; - const int * _noalias const stencil = list->stencil; - const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; - const int ntypes = atom->ntypes + 1; - const int nlocal = atom->nlocal; - - #ifndef _LMP_INTEL_OFFLOAD - int * const mask = atom->mask; - tagint * const molecule = atom->molecule; - #endif - - int tnum; - int *overflow; - double *timer_compute; - if (offload) { - timer_compute = fix->off_watch_neighbor(); - tnum = buffers->get_off_threads(); - overflow = fix->get_off_overflow_flag(); - fix->stop_watch(TIME_HOST_NEIGHBOR); - fix->start_watch(TIME_OFFLOAD_LATENCY); - } else { - tnum = comm->nthreads; - overflow = fix->get_overflow_flag(); - } - const int nthreads = tnum; - const int maxnbors = buffers->get_max_nbors(); - int * _noalias const atombin = buffers->get_atombin(); - const int * _noalias const binpacked = buffers->get_binpacked(); - - const int xperiodic = domain->xperiodic; - const int yperiodic = domain->yperiodic; - const int zperiodic = domain->zperiodic; - const flt_t xprd_half = domain->xprd_half; - const flt_t yprd_half = domain->yprd_half; - const flt_t zprd_half = domain->zprd_half; - - // Make sure dummy coordinates to eliminate loop remainder not within cutoff - { - const flt_t dx = (INTEL_BIGP - bboxhi[0]); - const flt_t dy = (INTEL_BIGP - bboxhi[1]); - const flt_t dz = (INTEL_BIGP - bboxhi[2]); - if (dx * dx + dy * dy + dz * dz < static_cast(cutneighmaxsq)) - error->one(FLERR, - "Intel package expects no atoms within cutoff of {1e15,1e15,1e15}."); - } - - #ifdef _LMP_INTEL_OFFLOAD - const int * _noalias const binhead = this->binhead; - const int * _noalias const bins = this->bins; - const int cop = fix->coprocessor_number(); - const int separate_buffers = fix->separate_buffers(); - #pragma offload target(mic:cop) if(offload) \ - in(x:length(e_nall+1) alloc_if(0) free_if(0)) \ - in(tag:length(tag_size) alloc_if(0) free_if(0)) \ - in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ - in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ - in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ - in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ - in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ - in(firstneigh:length(0) alloc_if(0) free_if(0)) \ - in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ - out(numneigh:length(0) alloc_if(0) free_if(0)) \ - in(ilist:length(0) alloc_if(0) free_if(0)) \ - in(atombin:length(aend) alloc_if(0) free_if(0)) \ - in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ - in(maxnbors,nthreads,maxspecial,nstencil,e_nall,offload,pack_width) \ - in(offload_end,separate_buffers,astart, aend, nlocal, molecular, ntypes) \ - in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ - out(overflow:length(5) alloc_if(0) free_if(0)) \ - out(timer_compute:length(1) alloc_if(0) free_if(0)) \ - signal(tag) - #endif - { - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime(); - #endif - - #ifdef _LMP_INTEL_OFFLOAD - overflow[LMP_LOCAL_MIN] = astart; - overflow[LMP_LOCAL_MAX] = aend - 1; - overflow[LMP_GHOST_MIN] = e_nall; - overflow[LMP_GHOST_MAX] = -1; - #endif - - int nstencilp = 0; - int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; - for (int k = 0; k < nstencil; k++) { - binstart[nstencilp] = stencil[k]; - int end = stencil[k] + 1; - for (int kk = k + 1; kk < nstencil; kk++) { - if (stencil[kk-1]+1 == stencil[kk]) { - end++; - k++; - } else break; - } - binend[nstencilp] = end; - nstencilp++; - } - - #if defined(_OPENMP) - #pragma omp parallel default(none) \ - shared(numneigh, overflow, nstencilp, binstart, binend) - #endif - { - #ifdef _LMP_INTEL_OFFLOAD - int lmin = e_nall, lmax = -1, gmin = e_nall, gmax = -1; - #endif - - const int num = aend - astart; - int tid, ifrom, ito; - - IP_PRE_omp_range_id_vec(ifrom, ito, tid, num, nthreads, pack_width); - ifrom += astart; - ito += astart; - int e_ito = ito; - if (ito == num) { - int imod = ito % pack_width; - if (imod) e_ito += pack_width - imod; - } - const int list_size = (e_ito + tid * 2 + 2) * maxnbors; - int which; - int pack_offset = maxnbors * pack_width; - int ct = (ifrom + tid * 2) * maxnbors; - int *neighptr = firstneigh + ct; - const int obound = pack_offset + maxnbors * 2; - - int max_chunk = 0; - int lane = 0; - for (int i = ifrom; i < ito; i++) { - const flt_t xtmp = x[i].x; - const flt_t ytmp = x[i].y; - const flt_t ztmp = x[i].z; - const int itype = x[i].w; - const tagint itag = tag[i]; - const int ioffset = ntypes * itype; - - const int ibin = atombin[i]; - int raw_count = pack_offset; - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - if (exclude) { - for (int k = 0; k < nstencilp; k++) { - const int bstart = binhead[ibin + binstart[k]]; - const int bend = binhead[ibin + binend[k]]; - #ifndef _LMP_INTEL_OFFLOAD - #ifdef INTEL_VMASK - #pragma simd - #endif - #endif - for (int jj = bstart; jj < bend; jj++) { - int j = binpacked[jj]; - - if (i == j) j=e_nall; - - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - if (j < nlocal) { - if (i < offload_end) continue; - } else if (offload) continue; - } - #endif - - #ifndef _LMP_INTEL_OFFLOAD - const int jtype = x[j].w; - if (exclusion(i,j,itype,jtype,mask,molecule)) continue; - #endif - - neighptr[raw_count++] = j; - } - } - } else { - for (int k = 0; k < nstencilp; k++) { - const int bstart = binhead[ibin + binstart[k]]; - const int bend = binhead[ibin + binend[k]]; - #ifndef _LMP_INTEL_OFFLOAD - #ifdef INTEL_VMASK - #pragma simd - #endif - #endif - for (int jj = bstart; jj < bend; jj++) { - int j = binpacked[jj]; - - if (i == j) j=e_nall; - - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - if (j < nlocal) { - if (i < offload_end) continue; - } else if (offload) continue; - } - #endif - - neighptr[raw_count++] = j; - } - } - } - - if (raw_count > obound) *overflow = 1; - - #if defined(LMP_SIMD_COMPILER) - #ifdef _LMP_INTEL_OFFLOAD - int vlmin = lmin, vlmax = lmax, vgmin = gmin, vgmax = gmax; - #if __INTEL_COMPILER+0 > 1499 - #pragma vector aligned - #pragma simd reduction(max:vlmax,vgmax) reduction(min:vlmin, vgmin) - #endif - #else - #pragma vector aligned - #pragma simd - #endif - #endif - for (int u = pack_offset; u < raw_count; u++) { - int j = neighptr[u]; - 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 int jtype = x[j].w; - const flt_t rsq = delx * delx + dely * dely + delz * delz; - if (rsq > cutneighsq[ioffset + jtype]) - neighptr[u] = e_nall; - else { - if (need_ic) { - int no_special; - ominimum_image_check(no_special, delx, dely, delz); - if (no_special) - neighptr[u] = -j - 1; - } - #ifdef _LMP_INTEL_OFFLOAD - if (j < nlocal) { - if (j < vlmin) vlmin = j; - if (j > vlmax) vlmax = j; - } else { - if (j < vgmin) vgmin = j; - if (j > vgmax) vgmax = j; - } - #endif - } - } - #ifdef _LMP_INTEL_OFFLOAD - lmin = MIN(lmin,vlmin); - gmin = MIN(gmin,vgmin); - lmax = MAX(lmax,vlmax); - gmax = MAX(gmax,vgmax); - #endif - - int n = lane, n2 = pack_offset; - for (int u = pack_offset; u < raw_count; u++) { - const int j = neighptr[u]; - int pj = j; - if (pj < e_nall) { - if (need_ic) - if (pj < 0) pj = -pj - 1; - - const int jtag = tag[pj]; - int flist = 0; - if (itag > jtag) { - if ((itag+jtag) % 2 == 0) flist = 1; - } else if (itag < jtag) { - if ((itag+jtag) % 2 == 1) flist = 1; - } else { - if (x[pj].z < ztmp) flist = 1; - else if (x[pj].z == ztmp && x[pj].y < ytmp) flist = 1; - else if (x[pj].z == ztmp && x[pj].y == ytmp && x[pj].x < xtmp) - flist = 1; - } - if (flist) { - neighptr[n2++] = j; - } else { - neighptr[n] = j; - n += pack_width; - } - } - } - int ns = (n - lane) / pack_width; - atombin[i] = ns; - for (int u = pack_offset; u < n2; u++) { - neighptr[n] = neighptr[u]; - n += pack_width; - } - - ilist[i] = i; - cnumneigh[i] = ct + lane; - ns += n2 - pack_offset; - numneigh[i] = ns; - - if (ns > max_chunk) max_chunk = ns; - lane++; - if (lane == pack_width) { - ct += max_chunk * pack_width; - const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); - const int edge = (ct % alignb); - if (edge) ct += alignb - edge; - neighptr = firstneigh + ct; - max_chunk = 0; - pack_offset = maxnbors * pack_width; - lane = 0; - if (ct + obound > list_size) { - if (i < ito - 1) { - *overflow = 1; - ct = (ifrom + tid * 2) * maxnbors; - } - } - } - } - - if (*overflow == 1) - for (int i = ifrom; i < ito; i++) - numneigh[i] = 0; - - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - #if defined(_OPENMP) - #pragma omp critical - #endif - { - if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; - if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; - if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; - if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; - } - #pragma omp barrier - } - - int ghost_offset = 0, nall_offset = e_nall; - if (separate_buffers) { - int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; - if (nghost < 0) nghost = 0; - if (offload) { - ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; - nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; - } else { - ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; - nall_offset = nlocal + nghost; - } - } - #endif - - if (molecular) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - - const int trip = jnum * pack_width; - for (int jj = 0; jj < trip; jj+=pack_width) { - const int j = jlist[jj]; - if (need_ic && j < 0) { - which = 0; - jlist[jj] = -j - 1; - } else - ofind_special(which, special, nspecial, i, tag[j]); - #ifdef _LMP_INTEL_OFFLOAD - if (j >= nlocal) { - if (j == e_nall) - jlist[jj] = nall_offset; - else if (which) - jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); - else jlist[jj]-=ghost_offset; - } else - #endif - if (which) jlist[jj] = j ^ (which << SBBITS); - } - } - } - #ifdef _LMP_INTEL_OFFLOAD - else if (separate_buffers) { - for (int i = ifrom; i < ito; ++i) { - int * _noalias jlist = firstneigh + cnumneigh[i]; - const int jnum = numneigh[i]; - int jj = 0; - for (jj = 0; jj < jnum; jj++) { - if (jlist[jj] >= nlocal) { - if (jlist[jj] == e_nall) jlist[jj] = nall_offset; - else jlist[jj] -= ghost_offset; - } - } - } - } - #endif - } // end omp - #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) - *timer_compute = MIC_Wtime() - *timer_compute; - #endif - } // end offload - - if (offload) { - fix->stop_watch(TIME_OFFLOAD_LATENCY); - #ifdef _LMP_INTEL_OFFLOAD - for (int n = 0; n < aend; n++) { - ilist[n] = n; - numneigh[n] = 0; - } - #endif - } else { - for (int i = astart; i < aend; i++) - list->firstneigh[i] = firstneigh + cnumneigh[i]; - fix->stop_watch(TIME_HOST_NEIGHBOR); - #ifdef _LMP_INTEL_OFFLOAD - if (separate_buffers) { - fix->start_watch(TIME_PACK); - fix->set_neighbor_host_sizes(); - buffers->pack_sep_from_single(fix->host_min_local(), - fix->host_used_local(), - fix->host_min_ghost(), - fix->host_used_ghost()); - fix->stop_watch(TIME_PACK); - } - #endif - } -} - diff --git a/src/USER-INTEL/npair_full_bin_intel.cpp b/src/USER-INTEL/npair_full_bin_intel.cpp new file mode 100644 index 0000000000..1ec93bf113 --- /dev/null +++ b/src/USER-INTEL/npair_full_bin_intel.cpp @@ -0,0 +1,552 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "npair_full_bin_intel.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "comm.h" +#include "group.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +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 USER-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 +void NPairFullBinIntel:: +fbi(NeighList *list, IntelBuffers *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, off_end, + _fix->nbor_pack_width()); + + int need_ic = 0; + if (atom->molecular) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + #ifdef _LMP_INTEL_OFFLOAD + if (need_ic) { + if (offload_noghost) { + fbi(1, list, buffers, 0, off_end); + fbi(0, list, buffers, host_start, nlocal, off_end); + } else { + fbi(1, list, buffers, 0, off_end); + fbi(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + fbi(1, list, buffers, 0, off_end); + fbi(0, list, buffers, host_start, nlocal, off_end); + } else { + fbi(1, list, buffers, 0, off_end); + fbi(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + fbi(0, list, buffers, host_start, nlocal); + else + fbi(0, list, buffers, host_start, nlocal); + #endif +} + +template +void NPairFullBinIntel:: +fbi(const int offload, NeighList *list, IntelBuffers *buffers, + const int astart, const int aend, const int offload_end) { + + if (aend-astart == 0) return; + + const int nall = atom->nlocal + atom->nghost; + int pad = 1; + int nall_t = nall; + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost && offload) nall_t = atom->nlocal; + #endif + + const int pack_width = _fix->nbor_pack_width(); + const int pad_width = pad; + + const ATOM_T * _noalias const x = buffers->get_x(); + int * _noalias const firstneigh = buffers->firstneigh(list); + const int e_nall = nall_t; + + const int molecular = atom->molecular; + int *ns = NULL; + tagint *s = NULL; + int tag_size = 0, special_size; + if (buffers->need_tag()) tag_size = e_nall; + if (molecular) { + s = atom->special[0]; + ns = atom->nspecial[0]; + special_size = aend; + } else { + s = &buffers->_special_holder; + ns = &buffers->_nspecial_holder; + special_size = 0; + } + const tagint * _noalias const special = s; + const int * _noalias const nspecial = ns; + const int maxspecial = atom->maxspecial; + const tagint * _noalias const tag = atom->tag; + + int * _noalias const ilist = list->ilist; + int * _noalias numneigh = list->numneigh; + int * _noalias const cnumneigh = buffers->cnumneigh(list); + const int nstencil = this->nstencil; + const int * _noalias const stencil = this->stencil; + const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; + const int ntypes = atom->ntypes + 1; + const int nlocal = atom->nlocal; + + #ifndef _LMP_INTEL_OFFLOAD + int * const mask = atom->mask; + tagint * const molecule = atom->molecule; + #endif + + int tnum; + int *overflow; + double *timer_compute; + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + timer_compute = _fix->off_watch_neighbor(); + tnum = buffers->get_off_threads(); + overflow = _fix->get_off_overflow_flag(); + _fix->stop_watch(TIME_HOST_NEIGHBOR); + _fix->start_watch(TIME_OFFLOAD_LATENCY); + } else + #endif + { + tnum = comm->nthreads; + overflow = _fix->get_overflow_flag(); + } + const int nthreads = tnum; + const int maxnbors = buffers->get_max_nbors(); + int * _noalias const atombin = buffers->get_atombin(); + const int * _noalias const binpacked = buffers->get_binpacked(); + + const int xperiodic = domain->xperiodic; + const int yperiodic = domain->yperiodic; + const int zperiodic = domain->zperiodic; + const flt_t xprd_half = domain->xprd_half; + const flt_t yprd_half = domain->yprd_half; + const flt_t zprd_half = domain->zprd_half; + + #ifdef _LMP_INTEL_OFFLOAD + const int * _noalias const binhead = this->binhead; + const int * _noalias const bins = this->bins; + const int cop = _fix->coprocessor_number(); + const int separate_buffers = _fix->separate_buffers(); + #pragma offload target(mic:cop) if(offload) \ + in(x:length(e_nall+1) alloc_if(0) free_if(0)) \ + in(tag:length(tag_size) alloc_if(0) free_if(0)) \ + in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ + in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ + in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ + in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ + in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ + in(firstneigh:length(0) alloc_if(0) free_if(0)) \ + in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ + out(numneigh:length(0) alloc_if(0) free_if(0)) \ + in(ilist:length(0) alloc_if(0) free_if(0)) \ + in(atombin:length(aend) alloc_if(0) free_if(0)) \ + in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ + in(maxnbors,nthreads,maxspecial,nstencil,e_nall,offload,pack_width) \ + in(offload_end,separate_buffers,astart, aend, nlocal, molecular, ntypes) \ + in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ + out(overflow:length(5) alloc_if(0) free_if(0)) \ + out(timer_compute:length(1) alloc_if(0) free_if(0)) \ + signal(tag) + #endif + { + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime(); + #endif + + #ifdef _LMP_INTEL_OFFLOAD + overflow[LMP_LOCAL_MIN] = astart; + overflow[LMP_LOCAL_MAX] = aend - 1; + overflow[LMP_GHOST_MIN] = e_nall; + overflow[LMP_GHOST_MAX] = -1; + #endif + + int nstencilp = 0; + int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; + for (int k = 0; k < nstencil; k++) { + binstart[nstencilp] = stencil[k]; + int end = stencil[k] + 1; + for (int kk = k + 1; kk < nstencil; kk++) { + if (stencil[kk-1]+1 == stencil[kk]) { + end++; + k++; + } else break; + } + binend[nstencilp] = end; + nstencilp++; + } + + #if defined(_OPENMP) + #pragma omp parallel default(none) \ + shared(numneigh, overflow, nstencilp, binstart, binend) + #endif + { + #ifdef _LMP_INTEL_OFFLOAD + int lmin = e_nall, lmax = -1, gmin = e_nall, gmax = -1; + #endif + + const int num = aend - astart; + int tid, ifrom, ito; + + IP_PRE_omp_range_id_vec(ifrom, ito, tid, num, nthreads, pack_width); + ifrom += astart; + ito += astart; + int e_ito = ito; + if (ito == num) { + int imod = ito % pack_width; + if (imod) e_ito += pack_width - imod; + } + const int list_size = (e_ito + tid * 2 + 2) * maxnbors; + int which; + int pack_offset = maxnbors * pack_width; + int ct = (ifrom + tid * 2) * maxnbors; + int *neighptr = firstneigh + ct; + const int obound = pack_offset + maxnbors * 2; + + int max_chunk = 0; + int lane = 0; + for (int i = ifrom; i < ito; i++) { + const flt_t xtmp = x[i].x; + const flt_t ytmp = x[i].y; + const flt_t ztmp = x[i].z; + const int itype = x[i].w; + const tagint itag = tag[i]; + const int ioffset = ntypes * itype; + + const int ibin = atombin[i]; + int raw_count = pack_offset; + + // loop over all atoms in surrounding bins in stencil including self + // skip i = j + if (exclude) { + for (int k = 0; k < nstencilp; k++) { + const int bstart = binhead[ibin + binstart[k]]; + const int bend = binhead[ibin + binend[k]]; + #ifndef _LMP_INTEL_OFFLOAD + #ifdef INTEL_VMASK + #pragma simd + #endif + #endif + for (int jj = bstart; jj < bend; jj++) { + int j = binpacked[jj]; + + if (i == j) j=e_nall; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost) { + if (j < nlocal) { + if (i < offload_end) continue; + } else if (offload) continue; + } + #endif + + #ifndef _LMP_INTEL_OFFLOAD + const int jtype = x[j].w; + if (exclusion(i,j,itype,jtype,mask,molecule)) continue; + #endif + + neighptr[raw_count++] = j; + } + } + } else { + for (int k = 0; k < nstencilp; k++) { + const int bstart = binhead[ibin + binstart[k]]; + const int bend = binhead[ibin + binend[k]]; + #ifndef _LMP_INTEL_OFFLOAD + #ifdef INTEL_VMASK + #pragma simd + #endif + #endif + for (int jj = bstart; jj < bend; jj++) { + int j = binpacked[jj]; + + if (i == j) j=e_nall; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost) { + if (j < nlocal) { + if (i < offload_end) continue; + } else if (offload) continue; + } + #endif + + neighptr[raw_count++] = j; + } + } + } + + if (raw_count > obound) *overflow = 1; + + #if defined(LMP_SIMD_COMPILER) + #ifdef _LMP_INTEL_OFFLOAD + int vlmin = lmin, vlmax = lmax, vgmin = gmin, vgmax = gmax; + #if __INTEL_COMPILER+0 > 1499 + #pragma vector aligned + #pragma simd reduction(max:vlmax,vgmax) reduction(min:vlmin, vgmin) + #endif + #else + #pragma vector aligned + #pragma simd + #endif + #endif + for (int u = pack_offset; u < raw_count; u++) { + int j = neighptr[u]; + 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 int jtype = x[j].w; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutneighsq[ioffset + jtype]) + neighptr[u] = e_nall; + else { + if (need_ic) { + int no_special; + ominimum_image_check(no_special, delx, dely, delz); + if (no_special) + neighptr[u] = -j - 1; + } + #ifdef _LMP_INTEL_OFFLOAD + if (j < nlocal) { + if (j < vlmin) vlmin = j; + if (j > vlmax) vlmax = j; + } else { + if (j < vgmin) vgmin = j; + if (j > vgmax) vgmax = j; + } + #endif + } + } + #ifdef _LMP_INTEL_OFFLOAD + lmin = MIN(lmin,vlmin); + gmin = MIN(gmin,vgmin); + lmax = MAX(lmax,vlmax); + gmax = MAX(gmax,vgmax); + #endif + + int n = lane, n2 = pack_offset; + for (int u = pack_offset; u < raw_count; u++) { + const int j = neighptr[u]; + int pj = j; + if (pj < e_nall) { + if (need_ic) + if (pj < 0) pj = -pj - 1; + + const int jtag = tag[pj]; + int flist = 0; + if (itag > jtag) { + if ((itag+jtag) % 2 == 0) flist = 1; + } else if (itag < jtag) { + if ((itag+jtag) % 2 == 1) flist = 1; + } else { + if (x[pj].z < ztmp) flist = 1; + else if (x[pj].z == ztmp && x[pj].y < ytmp) flist = 1; + else if (x[pj].z == ztmp && x[pj].y == ytmp && x[pj].x < xtmp) + flist = 1; + } + if (flist) { + neighptr[n2++] = j; + } else { + neighptr[n] = j; + n += pack_width; + } + } + } + int ns = (n - lane) / pack_width; + atombin[i] = ns; + for (int u = pack_offset; u < n2; u++) { + neighptr[n] = neighptr[u]; + n += pack_width; + } + + ilist[i] = i; + cnumneigh[i] = ct + lane; + ns += n2 - pack_offset; + numneigh[i] = ns; + + if (ns > max_chunk) max_chunk = ns; + lane++; + if (lane == pack_width) { + ct += max_chunk * pack_width; + const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); + const int edge = (ct % alignb); + if (edge) ct += alignb - edge; + neighptr = firstneigh + ct; + max_chunk = 0; + pack_offset = maxnbors * pack_width; + lane = 0; + if (ct + obound > list_size) { + if (i < ito - 1) { + *overflow = 1; + ct = (ifrom + tid * 2) * maxnbors; + } + } + } + } + + if (*overflow == 1) + for (int i = ifrom; i < ito; i++) + numneigh[i] = 0; + + #ifdef _LMP_INTEL_OFFLOAD + if (separate_buffers) { + #if defined(_OPENMP) + #pragma omp critical + #endif + { + if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; + if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; + if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; + if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; + } + #pragma omp barrier + } + + int ghost_offset = 0, nall_offset = e_nall; + if (separate_buffers) { + int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; + if (nghost < 0) nghost = 0; + if (offload) { + ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; + nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; + } else { + ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; + nall_offset = nlocal + nghost; + } + } + #endif + + if (molecular) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + + const int trip = jnum * pack_width; + for (int jj = 0; jj < trip; jj+=pack_width) { + const int j = jlist[jj]; + if (need_ic && j < 0) { + which = 0; + jlist[jj] = -j - 1; + } else + ofind_special(which, special, nspecial, i, tag[j]); + #ifdef _LMP_INTEL_OFFLOAD + if (j >= nlocal) { + if (j == e_nall) + jlist[jj] = nall_offset; + else if (which) + jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); + else jlist[jj]-=ghost_offset; + } else + #endif + if (which) jlist[jj] = j ^ (which << SBBITS); + } + } + } + #ifdef _LMP_INTEL_OFFLOAD + else if (separate_buffers) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + int jj = 0; + for (jj = 0; jj < jnum; jj++) { + if (jlist[jj] >= nlocal) { + if (jlist[jj] == e_nall) jlist[jj] = nall_offset; + else jlist[jj] -= ghost_offset; + } + } + } + } + #endif + } // end omp + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime() - *timer_compute; + #endif + } // end offload + + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + _fix->stop_watch(TIME_OFFLOAD_LATENCY); + _fix->start_watch(TIME_HOST_NEIGHBOR); + for (int n = 0; n < aend; n++) { + ilist[n] = n; + numneigh[n] = 0; + } + } else { + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + if (separate_buffers) { + _fix->start_watch(TIME_PACK); + _fix->set_neighbor_host_sizes(); + buffers->pack_sep_from_single(_fix->host_min_local(), + _fix->host_used_local(), + _fix->host_min_ghost(), + _fix->host_used_ghost()); + _fix->stop_watch(TIME_PACK); + } + } + #else + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + #endif +} diff --git a/src/USER-INTEL/npair_full_bin_intel.h b/src/USER-INTEL/npair_full_bin_intel.h new file mode 100644 index 0000000000..608bd0f5dd --- /dev/null +++ b/src/USER-INTEL/npair_full_bin_intel.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/bin/intel, + NPairFullBinIntel, + NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | + NP_INTEL) +#else + +#ifndef LMP_NPAIR_FULL_BIN_INTEL_H +#define LMP_NPAIR_FULL_BIN_INTEL_H + +#include "npair_intel.h" +#include "fix_intel.h" + +namespace LAMMPS_NS { + +class NPairFullBinIntel : public NPairIntel { + public: + NPairFullBinIntel(class LAMMPS *); + ~NPairFullBinIntel() {} + void build(class NeighList *); + + private: + template + void fbi(NeighList *, IntelBuffers *); + template + void fbi(const int, NeighList *, IntelBuffers *, const int, + const int, const int offload_end = 0); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-INTEL/npair_half_bin_newtoff_intel.cpp b/src/USER-INTEL/npair_half_bin_newtoff_intel.cpp new file mode 100644 index 0000000000..1fcc3f0759 --- /dev/null +++ b/src/USER-INTEL/npair_half_bin_newtoff_intel.cpp @@ -0,0 +1,451 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newtoff_intel.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "comm.h" +#include "group.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtoffIntel::NPairHalfBinNewtoffIntel(LAMMPS *lmp) : + NPairIntel(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 NPairHalfBinNewtoffIntel::build(NeighList *list) +{ + if (nstencil > INTEL_MAX_STENCIL_CHECK) + error->all(FLERR, "Too many neighbor bins for USER-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) + hbnni(list, _fix->get_mixed_buffers()); + else if (_fix->precision() == FixIntel::PREC_MODE_DOUBLE) + hbnni(list, _fix->get_double_buffers()); + else + hbnni(list, _fix->get_single_buffers()); + + _fix->stop_watch(TIME_HOST_NEIGHBOR); +} + +template +void NPairHalfBinNewtoffIntel:: +hbnni(NeighList *list, IntelBuffers *buffers) { + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + list->inum = nlocal; + + const int off_end = _fix->offload_end_neighbor(); + int host_start = off_end;; + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + #endif + + buffers->grow_list(list, atom->nlocal, comm->nthreads, off_end); + + int need_ic = 0; + if (atom->molecular) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + #ifdef _LMP_INTEL_OFFLOAD + if (need_ic) { + hbnni(1, list, buffers, 0, off_end); + hbnni(0, list, buffers, host_start, nlocal); + } else { + hbnni(1, list, buffers, 0, off_end); + hbnni(0, list, buffers, host_start, nlocal); + } + #else + if (need_ic) + hbnni(0, list, buffers, host_start, nlocal); + else + hbnni(0, list, buffers, host_start, nlocal); + #endif +} + +template +void NPairHalfBinNewtoffIntel:: +hbnni(const int offload, NeighList *list, IntelBuffers *buffers, + const int astart, const int aend) { + + if (aend-astart == 0) return; + + const int nall = atom->nlocal + atom->nghost; + int pad = 1; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + if (INTEL_MIC_NBOR_PAD > 1) + pad = INTEL_MIC_NBOR_PAD * sizeof(float) / sizeof(flt_t); + } else + #endif + if (INTEL_NBOR_PAD > 1) + pad = INTEL_NBOR_PAD * sizeof(float) / sizeof(flt_t); + const int pad_width = pad; + + const ATOM_T * _noalias const x = buffers->get_x(); + int * _noalias const firstneigh = buffers->firstneigh(list); + + const int molecular = atom->molecular; + int *ns = NULL; + tagint *s = NULL; + int tag_size = 0, special_size; + if (buffers->need_tag()) tag_size = nall; + if (molecular) { + s = atom->special[0]; + ns = atom->nspecial[0]; + special_size = aend; + } else { + s = &buffers->_special_holder; + ns = &buffers->_nspecial_holder; + special_size = 0; + } + const tagint * _noalias const special = s; + const int * _noalias const nspecial = ns; + const int maxspecial = atom->maxspecial; + const tagint * _noalias const tag = atom->tag; + + int * _noalias const ilist = list->ilist; + int * _noalias numneigh = list->numneigh; + int * _noalias const cnumneigh = buffers->cnumneigh(list); + const int nstencil = this->nstencil; + const int * _noalias const stencil = this->stencil; + const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; + const int ntypes = atom->ntypes + 1; + const int nlocal = atom->nlocal; + + #ifndef _LMP_INTEL_OFFLOAD + int * const mask = atom->mask; + tagint * const molecule = atom->molecule; + #endif + + int tnum; + int *overflow; + double *timer_compute; + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + timer_compute = _fix->off_watch_neighbor(); + tnum = buffers->get_off_threads(); + overflow = _fix->get_off_overflow_flag(); + _fix->stop_watch(TIME_HOST_NEIGHBOR); + _fix->start_watch(TIME_OFFLOAD_LATENCY); + } else + #endif + { + tnum = comm->nthreads; + overflow = _fix->get_overflow_flag(); + } + const int nthreads = tnum; + const int maxnbors = buffers->get_max_nbors(); + int * _noalias const atombin = buffers->get_atombin(); + const int * _noalias const binpacked = buffers->get_binpacked(); + + const int xperiodic = domain->xperiodic; + const int yperiodic = domain->yperiodic; + const int zperiodic = domain->zperiodic; + const flt_t xprd_half = domain->xprd_half; + const flt_t yprd_half = domain->yprd_half; + const flt_t zprd_half = domain->zprd_half; + + #ifdef _LMP_INTEL_OFFLOAD + const int * _noalias const binhead = this->binhead; + const int * _noalias const bins = this->bins; + const int cop = _fix->coprocessor_number(); + const int separate_buffers = _fix->separate_buffers(); + #pragma offload target(mic:cop) if(offload) \ + in(x:length(nall+1) alloc_if(0) free_if(0)) \ + in(tag:length(tag_size) alloc_if(0) free_if(0)) \ + in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ + in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ + in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ + in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ + in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ + in(firstneigh:length(0) alloc_if(0) free_if(0)) \ + in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ + out(numneigh:length(0) alloc_if(0) free_if(0)) \ + in(ilist:length(0) alloc_if(0) free_if(0)) \ + in(atombin:length(aend) alloc_if(0) free_if(0)) \ + in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ + in(maxnbors,nthreads,maxspecial,nstencil,pad_width,offload,nall) \ + in(separate_buffers, astart, aend, nlocal, molecular, ntypes) \ + in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ + out(overflow:length(5) alloc_if(0) free_if(0)) \ + out(timer_compute:length(1) alloc_if(0) free_if(0)) \ + signal(tag) + #endif + { + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime(); + #endif + + #ifdef _LMP_INTEL_OFFLOAD + overflow[LMP_LOCAL_MIN] = astart; + overflow[LMP_LOCAL_MAX] = aend - 1; + overflow[LMP_GHOST_MIN] = nall; + overflow[LMP_GHOST_MAX] = -1; + #endif + + int nstencilp = 0; + int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; + for (int k = 0; k < nstencil; k++) { + binstart[nstencilp] = stencil[k]; + int end = stencil[k] + 1; + for (int kk = k + 1; kk < nstencil; kk++) { + if (stencil[kk-1]+1 == stencil[kk]) { + end++; + k++; + } else break; + } + binend[nstencilp] = end; + nstencilp++; + } + + #if defined(_OPENMP) + #pragma omp parallel default(none) \ + shared(numneigh, overflow, nstencilp, binstart, binend) + #endif + { + #ifdef _LMP_INTEL_OFFLOAD + int lmin = nall, lmax = -1, gmin = nall, gmax = -1; + #endif + + const int num = aend - astart; + int tid, ifrom, ito; + IP_PRE_omp_range_id(ifrom, ito, tid, num, nthreads); + ifrom += astart; + ito += astart; + + int which; + + const int list_size = (ito + tid + 1) * maxnbors; + int ct = (ifrom + tid) * maxnbors; + int *neighptr = firstneigh + ct; + + for (int i = ifrom; i < ito; i++) { + int j, k, n, n2, itype, jtype, ibin; + double xtmp, ytmp, ztmp, delx, dely, delz, rsq; + + n = 0; + n2 = maxnbors; + + xtmp = x[i].x; + ytmp = x[i].y; + ztmp = x[i].z; + itype = x[i].w; + const int ioffset = ntypes*itype; + + // 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 = atombin[i]; + + for (k = 0; k < nstencilp; k++) { + const int bstart = binhead[ibin + binstart[k]]; + const int bend = binhead[ibin + binend[k]]; + for (int jj = bstart; jj < bend; jj++) { + const int j = binpacked[jj]; + if (j <= i) continue; + + jtype = x[j].w; + #ifndef _LMP_INTEL_OFFLOAD + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + #endif + + delx = xtmp - x[j].x; + dely = ytmp - x[j].y; + delz = ztmp - x[j].z; + rsq = delx * delx + dely * dely + delz * delz; + if (rsq <= cutneighsq[ioffset + jtype]) { + if (j < nlocal) { + if (need_ic) { + int no_special; + ominimum_image_check(no_special, delx, dely, delz); + if (no_special) + neighptr[n++] = -j - 1; + else + neighptr[n++] = j; + } else + neighptr[n++] = j; + #ifdef _LMP_INTEL_OFFLOAD + if (j < lmin) lmin = j; + if (j > lmax) lmax = j; + #endif + } else { + if (need_ic) { + int no_special; + ominimum_image_check(no_special, delx, dely, delz); + if (no_special) + neighptr[n2++] = -j - 1; + else + neighptr[n2++] = j; + } else + neighptr[n2++] = j; + #ifdef _LMP_INTEL_OFFLOAD + if (j < gmin) gmin = j; + if (j > gmax) gmax = j; + #endif + } + } + } + } + ilist[i] = i; + + cnumneigh[i] = ct; + if (n > maxnbors) *overflow = 1; + for (k = maxnbors; k < n2; k++) neighptr[n++] = neighptr[k]; + + const int edge = (n % pad_width); + if (edge) { + const int pad_end = n + (pad_width - edge); + #if defined(LMP_SIMD_COMPILER) + #pragma loop_count min=1, max=15, avg=8 + #endif + for ( ; n < pad_end; n++) + neighptr[n] = nall; + } + numneigh[i] = n; + while((n % (INTEL_DATA_ALIGN / sizeof(int))) != 0) n++; + ct += n; + neighptr += n; + if (ct + n + maxnbors > list_size) { + *overflow = 1; + ct = (ifrom + tid) * maxnbors; + } + } + + if (*overflow == 1) + for (int i = ifrom; i < ito; i++) + numneigh[i] = 0; + + #ifdef _LMP_INTEL_OFFLOAD + if (separate_buffers) { + #if defined(_OPENMP) + #pragma omp critical + #endif + { + if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; + if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; + if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; + if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; + } + #pragma omp barrier + } + + int ghost_offset = 0, nall_offset = nall; + if (separate_buffers) { + int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; + if (nghost < 0) nghost = 0; + if (offload) { + ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; + nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; + } else { + ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; + nall_offset = nlocal + nghost; + } + } + #endif + + if (molecular) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + for (int jj = 0; jj < jnum; jj++) { + const int j = jlist[jj]; + if (need_ic && j < 0) { + which = 0; + jlist[jj] = -j - 1; + } else + ofind_special(which, special, nspecial, i, tag[j]); + #ifdef _LMP_INTEL_OFFLOAD + if (j >= nlocal) { + if (j == nall) + jlist[jj] = nall_offset; + else if (which) + jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); + else jlist[jj]-=ghost_offset; + } else + #endif + if (which) jlist[jj] = j ^ (which << SBBITS); + } + } + } + #ifdef _LMP_INTEL_OFFLOAD + else if (separate_buffers) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + int jj = 0; + for (jj = 0; jj < jnum; jj++) + if (jlist[jj] >= nlocal) break; + while (jj < jnum) { + if (jlist[jj] == nall) jlist[jj] = nall_offset; + else jlist[jj] -= ghost_offset; + jj++; + } + } + } + #endif + } // end omp + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime() - *timer_compute; + #endif + } // end offload + + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + _fix->stop_watch(TIME_OFFLOAD_LATENCY); + _fix->start_watch(TIME_HOST_NEIGHBOR); + for (int n = 0; n < aend; n++) { + ilist[n] = n; + numneigh[n] = 0; + } + } else { + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + if (separate_buffers) { + _fix->start_watch(TIME_PACK); + _fix->set_neighbor_host_sizes(); + buffers->pack_sep_from_single(_fix->host_min_local(), + _fix->host_used_local(), + _fix->host_min_ghost(), + _fix->host_used_ghost()); + _fix->stop_watch(TIME_PACK); + } + } + #else + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + #endif +} diff --git a/src/USER-INTEL/npair_half_bin_newtoff_intel.h b/src/USER-INTEL/npair_half_bin_newtoff_intel.h new file mode 100644 index 0000000000..ccb4560909 --- /dev/null +++ b/src/USER-INTEL/npair_half_bin_newtoff_intel.h @@ -0,0 +1,52 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newtoff/intel, + NPairHalfBinNewtoffIntel, + NP_HALF | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_INTEL) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_INTEL_H +#define LMP_NPAIR_HALF_BIN_NEWTOFF_INTEL_H + +#include "npair_intel.h" +#include "fix_intel.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewtoffIntel : public NPairIntel { + public: + NPairHalfBinNewtoffIntel(class LAMMPS *); + ~NPairHalfBinNewtoffIntel() {} + void build(class NeighList *); + + private: + template + void hbnni(NeighList *, IntelBuffers *); + template + void hbnni(const int, NeighList *, IntelBuffers *, const int, + const int); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + + +*/ diff --git a/src/USER-INTEL/npair_half_bin_newton_intel.cpp b/src/USER-INTEL/npair_half_bin_newton_intel.cpp new file mode 100644 index 0000000000..5584f962e9 --- /dev/null +++ b/src/USER-INTEL/npair_half_bin_newton_intel.cpp @@ -0,0 +1,610 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newton_intel.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "comm.h" +#include "group.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 USER-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 +void NPairHalfBinNewtonIntel:: +hbni(NeighList *list, IntelBuffers *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, off_end); + + int need_ic = 0; + if (atom->molecular) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + #ifdef _LMP_INTEL_OFFLOAD + if (need_ic) { + if (offload_noghost) { + hbni(1, list, buffers, 0, off_end); + hbni(0, list, buffers, host_start, nlocal, off_end); + } else { + hbni(1, list, buffers, 0, off_end); + hbni(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + hbni(1, list, buffers, 0, off_end); + hbni(0, list, buffers, host_start, nlocal, off_end); + } else { + hbni(1, list, buffers, 0, off_end); + hbni(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + hbni(0, list, buffers, host_start, nlocal); + else + hbni(0, list, buffers, host_start, nlocal); + #endif +} + +template +void NPairHalfBinNewtonIntel:: +hbni(const int offload, NeighList *list, IntelBuffers *buffers, + const int astart, const int aend, const int offload_end) { + + if (aend-astart == 0) return; + + const int nall = atom->nlocal + atom->nghost; + int pad = 1; + int nall_t = nall; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost && offload) nall_t = atom->nlocal; + if (offload) { + if (INTEL_MIC_NBOR_PAD > 1) + pad = INTEL_MIC_NBOR_PAD * sizeof(float) / sizeof(flt_t); + } else + #endif + if (INTEL_NBOR_PAD > 1) + pad = INTEL_NBOR_PAD * sizeof(float) / sizeof(flt_t); + const int pad_width = pad; + + const ATOM_T * _noalias const x = buffers->get_x(); + int * _noalias const firstneigh = buffers->firstneigh(list); + const int e_nall = nall_t; + + const int molecular = atom->molecular; + int *ns = NULL; + tagint *s = NULL; + int tag_size = 0, special_size; + if (buffers->need_tag()) tag_size = e_nall; + if (molecular) { + s = atom->special[0]; + ns = atom->nspecial[0]; + special_size = aend; + } else { + s = &buffers->_special_holder; + ns = &buffers->_nspecial_holder; + special_size = 0; + } + const tagint * _noalias const special = s; + const int * _noalias const nspecial = ns; + const int maxspecial = atom->maxspecial; + const tagint * _noalias const tag = atom->tag; + + int * _noalias const ilist = list->ilist; + int * _noalias numneigh = list->numneigh; + int * _noalias const cnumneigh = buffers->cnumneigh(list); + const int nstencil = this->nstencil; + const int * _noalias const stencil = this->stencil; + const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; + const int ntypes = atom->ntypes + 1; + const int nlocal = atom->nlocal; + + #ifndef _LMP_INTEL_OFFLOAD + int * const mask = atom->mask; + tagint * const molecule = atom->molecule; + #endif + + int tnum; + int *overflow; + double *timer_compute; + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + timer_compute = _fix->off_watch_neighbor(); + tnum = buffers->get_off_threads(); + overflow = _fix->get_off_overflow_flag(); + _fix->stop_watch(TIME_HOST_NEIGHBOR); + _fix->start_watch(TIME_OFFLOAD_LATENCY); + } else + #endif + { + tnum = comm->nthreads; + overflow = _fix->get_overflow_flag(); + } + const int nthreads = tnum; + const int maxnbors = buffers->get_max_nbors(); + int * _noalias const atombin = buffers->get_atombin(); + const int * _noalias const binpacked = buffers->get_binpacked(); + + const int xperiodic = domain->xperiodic; + const int yperiodic = domain->yperiodic; + const int zperiodic = domain->zperiodic; + const flt_t xprd_half = domain->xprd_half; + const flt_t yprd_half = domain->yprd_half; + const flt_t zprd_half = domain->zprd_half; + + #ifdef _LMP_INTEL_OFFLOAD + const int * _noalias const binhead = this->binhead; + const int * _noalias const bins = this->bins; + const int cop = _fix->coprocessor_number(); + const int separate_buffers = _fix->separate_buffers(); + #pragma offload target(mic:cop) if(offload) \ + in(x:length(e_nall+1) alloc_if(0) free_if(0)) \ + in(tag:length(tag_size) alloc_if(0) free_if(0)) \ + in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ + in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ + in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ + in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ + in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ + in(firstneigh:length(0) alloc_if(0) free_if(0)) \ + in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ + out(numneigh:length(0) alloc_if(0) free_if(0)) \ + in(ilist:length(0) alloc_if(0) free_if(0)) \ + in(atombin:length(aend) alloc_if(0) free_if(0)) \ + in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ + in(maxnbors,nthreads,maxspecial,nstencil,e_nall,offload,pad_width) \ + in(offload_end,separate_buffers,astart, aend, nlocal, molecular, ntypes) \ + in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ + out(overflow:length(5) alloc_if(0) free_if(0)) \ + out(timer_compute:length(1) alloc_if(0) free_if(0)) \ + signal(tag) + #endif + { + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime(); + #endif + + #ifdef _LMP_INTEL_OFFLOAD + overflow[LMP_LOCAL_MIN] = astart; + overflow[LMP_LOCAL_MAX] = aend - 1; + overflow[LMP_GHOST_MIN] = e_nall; + overflow[LMP_GHOST_MAX] = -1; + #endif + + int nstencilp = 0; + int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; + for (int k = 0; k < nstencil; k++) { + binstart[nstencilp] = stencil[k]; + int end = stencil[k] + 1; + for (int kk = k + 1; kk < nstencil; kk++) { + if (stencil[kk-1]+1 == stencil[kk]) { + end++; + k++; + } else break; + } + binend[nstencilp] = end; + nstencilp++; + } + + #if defined(_OPENMP) + #pragma omp parallel default(none) \ + shared(numneigh, overflow, nstencilp, binstart, binend) + #endif + { + #ifdef _LMP_INTEL_OFFLOAD + int lmin = e_nall, lmax = -1, gmin = e_nall, gmax = -1; + #endif + + const int num = aend - astart; + int tid, ifrom, ito; + + #ifdef OUTER_CHUNK + const int swidth = ip_simd::SIMD_type::width(); + IP_PRE_omp_range_id_vec(ifrom, ito, tid, num, nthreads, swidth); + ifrom += astart; + ito += astart; + int e_ito = ito; + if (ito == num) { + int imod = ito % swidth; + if (imod) e_ito += swidth - imod; + } + const int list_size = (e_ito + tid * 2 + 2) * maxnbors; + #else + const int swidth = 1; + IP_PRE_omp_range_id(ifrom, ito, tid, num, nthreads); + ifrom += astart; + ito += astart; + const int list_size = (ito + tid * 2 + 2) * maxnbors; + #endif + + int which; + + int pack_offset = maxnbors * swidth; + int ct = (ifrom + tid * 2) * maxnbors; + int *neighptr = firstneigh + ct; + const int obound = pack_offset + maxnbors * 2; + + int max_chunk = 0; + int lane = 0; + for (int i = ifrom; i < ito; i++) { + const flt_t xtmp = x[i].x; + const flt_t ytmp = x[i].y; + const flt_t ztmp = x[i].z; + const int itype = x[i].w; + const int ioffset = ntypes * itype; + + // 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/to the right" of i + + int raw_count = pack_offset; + for (int j = bins[i]; j >= 0; j = bins[j]) { + if (j >= nlocal) { + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost && offload) continue; + #endif + if (x[j].z < ztmp) continue; + if (x[j].z == ztmp) { + if (x[j].y < ytmp) continue; + if (x[j].y == ytmp && x[j].x < xtmp) continue; + } + } + #ifdef _LMP_INTEL_OFFLOAD + else if (offload_noghost && i < offload_end) continue; + #endif + + #ifndef _LMP_INTEL_OFFLOAD + if (exclude) { + const int jtype = x[j].w; + if (exclusion(i,j,itype,jtype,mask,molecule)) continue; + } + #endif + + neighptr[raw_count++] = j; + } + + // loop over all atoms in other bins in stencil, store every pair + + const int ibin = atombin[i]; + if (exclude) { + for (int k = 0; k < nstencilp; k++) { + const int bstart = binhead[ibin + binstart[k]]; + const int bend = binhead[ibin + binend[k]]; + #ifndef _LMP_INTEL_OFFLOAD + #ifdef INTEL_VMASK + #pragma simd + #endif + #endif + for (int jj = bstart; jj < bend; jj++) { + const int j = binpacked[jj]; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost) { + if (j < nlocal) { + if (i < offload_end) continue; + } else if (offload) continue; + } + #endif + + #ifndef _LMP_INTEL_OFFLOAD + const int jtype = x[j].w; + if (exclusion(i,j,itype,jtype,mask,molecule)) continue; + #endif + + neighptr[raw_count++] = j; + } + } + } else { + for (int k = 0; k < nstencilp; k++) { + const int bstart = binhead[ibin + binstart[k]]; + const int bend = binhead[ibin + binend[k]]; + #ifndef _LMP_INTEL_OFFLOAD + #ifdef INTEL_VMASK + #pragma simd + #endif + #endif + for (int jj = bstart; jj < bend; jj++) { + const int j = binpacked[jj]; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost) { + if (j < nlocal) { + if (i < offload_end) continue; + } else if (offload) continue; + } + #endif + + neighptr[raw_count++] = j; + } + } + } + + if (raw_count > obound) *overflow = 1; + + #if defined(LMP_SIMD_COMPILER) + #ifdef _LMP_INTEL_OFFLOAD + int vlmin = lmin, vlmax = lmax, vgmin = gmin, vgmax = gmax; + #if __INTEL_COMPILER+0 > 1499 + #pragma vector aligned + #pragma simd reduction(max:vlmax,vgmax) reduction(min:vlmin, vgmin) + #endif + #else + #pragma vector aligned + #pragma simd + #endif + #endif + for (int u = pack_offset; u < raw_count; u++) { + int j = neighptr[u]; + 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 int jtype = x[j].w; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutneighsq[ioffset + jtype]) + neighptr[u] = e_nall; + else { + if (need_ic) { + int no_special; + ominimum_image_check(no_special, delx, dely, delz); + if (no_special) + neighptr[u] = -j - 1; + } + #ifdef _LMP_INTEL_OFFLOAD + if (j < nlocal) { + if (j < vlmin) vlmin = j; + if (j > vlmax) vlmax = j; + } else { + if (j < vgmin) vgmin = j; + if (j > vgmax) vgmax = j; + } + #endif + } + } + #ifdef _LMP_INTEL_OFFLOAD + lmin = MIN(lmin,vlmin); + gmin = MIN(gmin,vgmin); + lmax = MAX(lmax,vlmax); + gmax = MAX(gmax,vgmax); + #endif + + int n = lane, n2 = pack_offset; + for (int u = pack_offset; u < raw_count; u++) { + const int j = neighptr[u]; + int pj = j; + if (pj < e_nall) { + if (need_ic) + if (pj < 0) pj = -pj - 1; + + if (pj < nlocal) { + neighptr[n] = j; + n += swidth; + } else + neighptr[n2++] = j; + } + } + int ns = (n - lane) / swidth; + for (int u = pack_offset; u < n2; u++) { + neighptr[n] = neighptr[u]; + n += swidth; + } + + ilist[i] = i; + cnumneigh[i] = ct + lane; + ns += n2 - pack_offset; + #ifndef OUTER_CHUNK + int edge = (ns % pad_width); + if (edge) { + const int pad_end = ns + (pad_width - edge); + #if defined(LMP_SIMD_COMPILER) + #pragma loop_count min=1, max=15, avg=8 + #endif + for ( ; ns < pad_end; ns++) + neighptr[ns] = e_nall; + } + #endif + numneigh[i] = ns; + + #ifdef OUTER_CHUNK + if (ns > max_chunk) max_chunk = ns; + lane++; + if (lane == swidth) { + ct += max_chunk * swidth; + const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); + int edge = (ct % alignb); + if (edge) ct += alignb - edge; + neighptr = firstneigh + ct; + max_chunk = 0; + pack_offset = maxnbors * swidth; + lane = 0; + if (ct + obound > list_size) { + if (i < ito - 1) { + *overflow = 1; + ct = (ifrom + tid * 2) * maxnbors; + } + } + } + #else + ct += ns; + const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); + edge = (ct % alignb); + if (edge) ct += alignb - edge; + neighptr = firstneigh + ct; + if (ct + obound > list_size) { + if (i < ito - 1) { + *overflow = 1; + ct = (ifrom + tid * 2) * maxnbors; + } + } + #endif + } + + if (*overflow == 1) + for (int i = ifrom; i < ito; i++) + numneigh[i] = 0; + + #ifdef _LMP_INTEL_OFFLOAD + if (separate_buffers) { + #if defined(_OPENMP) + #pragma omp critical + #endif + { + if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; + if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; + if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; + if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; + } + #pragma omp barrier + } + + int ghost_offset = 0, nall_offset = e_nall; + if (separate_buffers) { + int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; + if (nghost < 0) nghost = 0; + if (offload) { + ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; + nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; + } else { + ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; + nall_offset = nlocal + nghost; + } + } + #endif + + if (molecular) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + #ifndef OUTER_CHUNK + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma simd + #endif + for (int jj = 0; jj < jnum; jj++) { + #else + const int trip = jnum * swidth; + for (int jj = 0; jj < trip; jj+= swidth) { + #endif + const int j = jlist[jj]; + if (need_ic && j < 0) { + which = 0; + jlist[jj] = -j - 1; + } else + ofind_special(which, special, nspecial, i, tag[j]); + #ifdef _LMP_INTEL_OFFLOAD + if (j >= nlocal) { + if (j == e_nall) + jlist[jj] = nall_offset; + else if (which) + jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); + else jlist[jj]-=ghost_offset; + } else + #endif + if (which) jlist[jj] = j ^ (which << SBBITS); + } + } + } + #ifdef _LMP_INTEL_OFFLOAD + else if (separate_buffers) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + int jj = 0; + for (jj = 0; jj < jnum; jj++) + if (jlist[jj] >= nlocal) break; + while (jj < jnum) { + if (jlist[jj] == e_nall) jlist[jj] = nall_offset; + else jlist[jj] -= ghost_offset; + jj++; + } + } + } + #endif + } // end omp + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime() - *timer_compute; + #endif + } // end offload + + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + _fix->stop_watch(TIME_OFFLOAD_LATENCY); + _fix->start_watch(TIME_HOST_NEIGHBOR); + for (int n = 0; n < aend; n++) { + ilist[n] = n; + numneigh[n] = 0; + } + } else { + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + if (separate_buffers) { + _fix->start_watch(TIME_PACK); + _fix->set_neighbor_host_sizes(); + buffers->pack_sep_from_single(_fix->host_min_local(), + _fix->host_used_local(), + _fix->host_min_ghost(), + _fix->host_used_ghost()); + _fix->stop_watch(TIME_PACK); + } + } + #else + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + #endif +} diff --git a/src/USER-INTEL/npair_half_bin_newton_intel.h b/src/USER-INTEL/npair_half_bin_newton_intel.h new file mode 100644 index 0000000000..4e496986b4 --- /dev/null +++ b/src/USER-INTEL/npair_half_bin_newton_intel.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newton/intel, + NPairHalfBinNewtonIntel, + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_INTEL) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTON_INTEL_H +#define LMP_NPAIR_HALF_BIN_NEWTON_INTEL_H + +#include "npair_intel.h" +#include "fix_intel.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewtonIntel : public NPairIntel { + public: + NPairHalfBinNewtonIntel(class LAMMPS *); + ~NPairHalfBinNewtonIntel() {} + void build(class NeighList *); + + private: + template + void hbni(NeighList *, IntelBuffers *); + template + void hbni(const int, NeighList *, IntelBuffers *, const int, + const int, const int offload_end = 0); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-INTEL/npair_half_bin_newton_tri_intel.cpp b/src/USER-INTEL/npair_half_bin_newton_tri_intel.cpp new file mode 100644 index 0000000000..3b6d68d4de --- /dev/null +++ b/src/USER-INTEL/npair_half_bin_newton_tri_intel.cpp @@ -0,0 +1,513 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newton_tri_intel.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "comm.h" +#include "group.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 USER-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 +void NPairHalfBinNewtonTriIntel:: +hbnti(NeighList *list, IntelBuffers *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, off_end); + + int need_ic = 0; + if (atom->molecular) + dminimum_image_check(need_ic, neighbor->cutneighmax, neighbor->cutneighmax, + neighbor->cutneighmax); + + #ifdef _LMP_INTEL_OFFLOAD + if (need_ic) { + if (offload_noghost) { + hbnti(1, list, buffers, 0, off_end); + hbnti(0, list, buffers, host_start, nlocal, off_end); + } else { + hbnti(1, list, buffers, 0, off_end); + hbnti(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + hbnti(1, list, buffers, 0, off_end); + hbnti(0, list, buffers, host_start, nlocal, off_end); + } else { + hbnti(1, list, buffers, 0, off_end); + hbnti(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + hbnti(0, list, buffers, host_start, nlocal); + else + hbnti(0, list, buffers, host_start, nlocal); + #endif +} + +template +void NPairHalfBinNewtonTriIntel:: +hbnti(const int offload, NeighList *list, IntelBuffers *buffers, + const int astart, const int aend, const int offload_end) { + if (aend-astart == 0) return; + + const int nall = atom->nlocal + atom->nghost; + int pad = 1; + int nall_t = nall; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost && offload) nall_t = atom->nlocal; + if (offload) { + if (INTEL_MIC_NBOR_PAD > 1) + pad = INTEL_MIC_NBOR_PAD * sizeof(float) / sizeof(flt_t); + } else + #endif + if (INTEL_NBOR_PAD > 1) + pad = INTEL_NBOR_PAD * sizeof(float) / sizeof(flt_t); + const int pad_width = pad; + + const ATOM_T * _noalias const x = buffers->get_x(); + int * _noalias const firstneigh = buffers->firstneigh(list); + const int e_nall = nall_t; + + const int molecular = atom->molecular; + int *ns = NULL; + tagint *s = NULL; + int tag_size = 0, special_size; + if (buffers->need_tag()) tag_size = e_nall; + if (molecular) { + s = atom->special[0]; + ns = atom->nspecial[0]; + special_size = aend; + } else { + s = &buffers->_special_holder; + ns = &buffers->_nspecial_holder; + special_size = 0; + } + const tagint * _noalias const special = s; + const int * _noalias const nspecial = ns; + const int maxspecial = atom->maxspecial; + const tagint * _noalias const tag = atom->tag; + + int * _noalias const ilist = list->ilist; + int * _noalias numneigh = list->numneigh; + int * _noalias const cnumneigh = buffers->cnumneigh(list); + const int nstencil = this->nstencil; + const int * _noalias const stencil = this->stencil; + const flt_t * _noalias const cutneighsq = buffers->get_cutneighsq()[0]; + const int ntypes = atom->ntypes + 1; + const int nlocal = atom->nlocal; + + #ifndef _LMP_INTEL_OFFLOAD + int * const mask = atom->mask; + tagint * const molecule = atom->molecule; + #endif + + int tnum; + int *overflow; + double *timer_compute; + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + timer_compute = _fix->off_watch_neighbor(); + tnum = buffers->get_off_threads(); + overflow = _fix->get_off_overflow_flag(); + _fix->stop_watch(TIME_HOST_NEIGHBOR); + _fix->start_watch(TIME_OFFLOAD_LATENCY); + } else + #endif + { + tnum = comm->nthreads; + overflow = _fix->get_overflow_flag(); + } + const int nthreads = tnum; + const int maxnbors = buffers->get_max_nbors(); + int * _noalias const atombin = buffers->get_atombin(); + const int * _noalias const binpacked = buffers->get_binpacked(); + + const int xperiodic = domain->xperiodic; + const int yperiodic = domain->yperiodic; + const int zperiodic = domain->zperiodic; + const flt_t xprd_half = domain->xprd_half; + const flt_t yprd_half = domain->yprd_half; + const flt_t zprd_half = domain->zprd_half; + + #ifdef _LMP_INTEL_OFFLOAD + const int * _noalias const binhead = this->binhead; + const int * _noalias const bins = this->bins; + const int cop = _fix->coprocessor_number(); + const int separate_buffers = _fix->separate_buffers(); + #pragma offload target(mic:cop) if(offload) \ + in(x:length(e_nall+1) alloc_if(0) free_if(0)) \ + in(tag:length(tag_size) alloc_if(0) free_if(0)) \ + in(special:length(special_size*maxspecial) alloc_if(0) free_if(0)) \ + in(nspecial:length(special_size*3) alloc_if(0) free_if(0)) \ + in(bins,binpacked:length(nall) alloc_if(0) free_if(0)) \ + in(binhead:length(mbins+1) alloc_if(0) free_if(0)) \ + in(cutneighsq:length(0) alloc_if(0) free_if(0)) \ + in(firstneigh:length(0) alloc_if(0) free_if(0)) \ + in(cnumneigh:length(0) alloc_if(0) free_if(0)) \ + out(numneigh:length(0) alloc_if(0) free_if(0)) \ + in(ilist:length(0) alloc_if(0) free_if(0)) \ + in(atombin:length(aend) alloc_if(0) free_if(0)) \ + in(stencil:length(nstencil) alloc_if(0) free_if(0)) \ + in(maxnbors,nthreads,maxspecial,nstencil,offload_end,pad_width,e_nall) \ + in(offload,separate_buffers, astart, aend, nlocal, molecular, ntypes) \ + in(xperiodic, yperiodic, zperiodic, xprd_half, yprd_half, zprd_half) \ + out(overflow:length(5) alloc_if(0) free_if(0)) \ + out(timer_compute:length(1) alloc_if(0) free_if(0)) \ + signal(tag) + #endif + { + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime(); + #endif + + #ifdef _LMP_INTEL_OFFLOAD + overflow[LMP_LOCAL_MIN] = astart; + overflow[LMP_LOCAL_MAX] = aend - 1; + overflow[LMP_GHOST_MIN] = e_nall; + overflow[LMP_GHOST_MAX] = -1; + #endif + + int nstencilp = 0; + int binstart[INTEL_MAX_STENCIL], binend[INTEL_MAX_STENCIL]; + for (int k = 0; k < nstencil; k++) { + binstart[nstencilp] = stencil[k]; + int end = stencil[k] + 1; + for (int kk = k + 1; kk < nstencil; kk++) { + if (stencil[kk-1]+1 == stencil[kk]) { + end++; + k++; + } else break; + } + binend[nstencilp] = end; + nstencilp++; + } + + #if defined(_OPENMP) + #pragma omp parallel default(none) \ + shared(numneigh, overflow, nstencilp, binstart, binend) + #endif + { + #ifdef _LMP_INTEL_OFFLOAD + int lmin = e_nall, lmax = -1, gmin = e_nall, gmax = -1; + #endif + + const int num = aend - astart; + int tid, ifrom, ito; + IP_PRE_omp_range_id(ifrom, ito, tid, num, nthreads); + ifrom += astart; + ito += astart; + + int which; + + const int list_size = (ito + tid * 2 + 2) * maxnbors; + int ct = (ifrom + tid * 2) * maxnbors; + int *neighptr = firstneigh + ct; + const int obound = maxnbors * 3; + + for (int i = ifrom; i < ito; i++) { + const flt_t xtmp = x[i].x; + const flt_t ytmp = x[i].y; + const flt_t ztmp = x[i].z; + const int itype = x[i].w; + const int ioffset = ntypes * itype; + + // loop over all atoms in bins in stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + const int ibin = atombin[i]; + + int raw_count = maxnbors; + for (int k = 0; k < nstencilp; k++) { + const int bstart = binhead[ibin + binstart[k]]; + const int bend = binhead[ibin + binend[k]]; + for (int jj = bstart; jj < bend; jj++) { + const int j = binpacked[jj]; + + #ifdef _LMP_INTEL_OFFLOAD + if (offload_noghost) { + if (j < nlocal) { + if (i < offload_end) continue; + } else if (offload) continue; + } + #endif + + if (x[j].z < ztmp) continue; + if (x[j].z == ztmp) { + if (x[j].y < ytmp) continue; + if (x[j].y == ytmp) { + if (x[j].x < xtmp) continue; + if (x[j].x == xtmp && j <= i) continue; + } + } + + #ifndef _LMP_INTEL_OFFLOAD + if (exclude) { + const int jtype = x[j].w; + if (exclusion(i,j,itype,jtype,mask,molecule)) continue; + } + #endif + + neighptr[raw_count++] = j; + } + } + if (raw_count > obound) + *overflow = 1; + + #if defined(LMP_SIMD_COMPILER) + #ifdef _LMP_INTEL_OFFLOAD + int vlmin = lmin, vlmax = lmax, vgmin = gmin, vgmax = gmax; + #if __INTEL_COMPILER+0 > 1499 + #pragma vector aligned + #pragma simd reduction(max:vlmax,vgmax) reduction(min:vlmin, vgmin) + #endif + #else + #pragma vector aligned + #pragma simd + #endif + #endif + for (int u = maxnbors; u < raw_count; u++) { + int j = neighptr[u]; + 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 int jtype = x[j].w; + const flt_t rsq = delx * delx + dely * dely + delz * delz; + if (rsq > cutneighsq[ioffset + jtype]) + neighptr[u] = e_nall; + else { + if (need_ic) { + int no_special; + ominimum_image_check(no_special, delx, dely, delz); + if (no_special) + neighptr[u] = -j - 1; + } + + #ifdef _LMP_INTEL_OFFLOAD + if (j < nlocal) { + if (j < vlmin) vlmin = j; + if (j > vlmax) vlmax = j; + } else { + if (j < vgmin) vgmin = j; + if (j > vgmax) vgmax = j; + } + #endif + } + } + + int n = 0, n2 = maxnbors; + for (int u = maxnbors; u < raw_count; u++) { + const int j = neighptr[u]; + int pj = j; + if (pj < e_nall) { + if (need_ic) + if (pj < 0) pj = -pj - 1; + + if (pj < nlocal) + neighptr[n++] = j; + else + neighptr[n2++] = j; + } + } + int ns = n; + for (int u = maxnbors; u < n2; u++) + neighptr[n++] = neighptr[u]; + + ilist[i] = i; + cnumneigh[i] = ct; + ns += n2 - maxnbors; + + int edge = (ns % pad_width); + if (edge) { + const int pad_end = ns + (pad_width - edge); + #if defined(LMP_SIMD_COMPILER) + #pragma loop_count min=1, max=15, avg=8 + #endif + for ( ; ns < pad_end; ns++) + neighptr[ns] = e_nall; + } + numneigh[i] = ns; + + ct += ns; + const int alignb = (INTEL_DATA_ALIGN / sizeof(int)); + edge = (ct % alignb); + if (edge) ct += alignb - edge; + neighptr = firstneigh + ct; + if (ct + obound > list_size) { + if (i < ito - 1) { + *overflow = 1; + ct = (ifrom + tid * 2) * maxnbors; + } + } + } + + if (*overflow == 1) + for (int i = ifrom; i < ito; i++) + numneigh[i] = 0; + + #ifdef _LMP_INTEL_OFFLOAD + if (separate_buffers) { + #if defined(_OPENMP) + #pragma omp critical + #endif + { + if (lmin < overflow[LMP_LOCAL_MIN]) overflow[LMP_LOCAL_MIN] = lmin; + if (lmax > overflow[LMP_LOCAL_MAX]) overflow[LMP_LOCAL_MAX] = lmax; + if (gmin < overflow[LMP_GHOST_MIN]) overflow[LMP_GHOST_MIN] = gmin; + if (gmax > overflow[LMP_GHOST_MAX]) overflow[LMP_GHOST_MAX] = gmax; + } + #pragma omp barrier + } + + int ghost_offset = 0, nall_offset = e_nall; + if (separate_buffers) { + int nghost = overflow[LMP_GHOST_MAX] + 1 - overflow[LMP_GHOST_MIN]; + if (nghost < 0) nghost = 0; + if (offload) { + ghost_offset = overflow[LMP_GHOST_MIN] - overflow[LMP_LOCAL_MAX] - 1; + nall_offset = overflow[LMP_LOCAL_MAX] + 1 + nghost; + } else { + ghost_offset = overflow[LMP_GHOST_MIN] - nlocal; + nall_offset = nlocal + nghost; + } + } + #endif + + if (molecular) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + #if defined(LMP_SIMD_COMPILER) + #pragma vector aligned + #pragma simd + #endif + for (int jj = 0; jj < jnum; jj++) { + const int j = jlist[jj]; + if (need_ic && j < 0) { + which = 0; + jlist[jj] = -j - 1; + } else + ofind_special(which, special, nspecial, i, tag[j]); + #ifdef _LMP_INTEL_OFFLOAD + if (j >= nlocal) { + if (j == e_nall) + jlist[jj] = nall_offset; + else if (which) + jlist[jj] = (j-ghost_offset) ^ (which << SBBITS); + else jlist[jj]-=ghost_offset; + } else + #endif + if (which) jlist[jj] = j ^ (which << SBBITS); + } + } + } + #ifdef _LMP_INTEL_OFFLOAD + else if (separate_buffers) { + for (int i = ifrom; i < ito; ++i) { + int * _noalias jlist = firstneigh + cnumneigh[i]; + const int jnum = numneigh[i]; + int jj = 0; + for (jj = 0; jj < jnum; jj++) + if (jlist[jj] >= nlocal) break; + while (jj < jnum) { + if (jlist[jj] == e_nall) jlist[jj] = nall_offset; + else jlist[jj] -= ghost_offset; + jj++; + } + } + } + #endif + } // end omp + #if defined(__MIC__) && defined(_LMP_INTEL_OFFLOAD) + *timer_compute = MIC_Wtime() - *timer_compute; + #endif + } // end offload + + #ifdef _LMP_INTEL_OFFLOAD + if (offload) { + _fix->stop_watch(TIME_OFFLOAD_LATENCY); + _fix->start_watch(TIME_HOST_NEIGHBOR); + for (int n = 0; n < aend; n++) { + ilist[n] = n; + numneigh[n] = 0; + } + } else { + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + if (separate_buffers) { + _fix->start_watch(TIME_PACK); + _fix->set_neighbor_host_sizes(); + buffers->pack_sep_from_single(_fix->host_min_local(), + _fix->host_used_local(), + _fix->host_min_ghost(), + _fix->host_used_ghost()); + _fix->stop_watch(TIME_PACK); + } + } + #else + for (int i = astart; i < aend; i++) + list->firstneigh[i] = firstneigh + cnumneigh[i]; + #endif +} diff --git a/src/USER-INTEL/npair_half_bin_newton_tri_intel.h b/src/USER-INTEL/npair_half_bin_newton_tri_intel.h new file mode 100644 index 0000000000..d1b9ee9cd1 --- /dev/null +++ b/src/USER-INTEL/npair_half_bin_newton_tri_intel.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newton/tri/intel, + NPairHalfBinNewtonTriIntel, + NP_HALF | NP_BIN | NP_NEWTON | NP_TRI | NP_INTEL) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTON_INTEL_TRI_H +#define LMP_NPAIR_HALF_BIN_NEWTON_INTEL_TRI_H + +#include "npair_intel.h" +#include "fix_intel.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewtonTriIntel : public NPairIntel { + public: + NPairHalfBinNewtonTriIntel(class LAMMPS *); + ~NPairHalfBinNewtonTriIntel() {} + void build(class NeighList *); + + private: + template + void hbnti(NeighList *, IntelBuffers *); + template + void hbnti(const int, NeighList *, IntelBuffers *, const int, + const int, const int offload_end = 0); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-INTEL/npair_intel.cpp b/src/USER-INTEL/npair_intel.cpp new file mode 100644 index 0000000000..8ec40260f3 --- /dev/null +++ b/src/USER-INTEL/npair_intel.cpp @@ -0,0 +1,69 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +/* ---------------------------------------------------------------------- + Contributing author: W. Michael Brown (Intel) +------------------------------------------------------------------------- */ + +#include "npair_intel.h" +#include "nstencil.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairIntel::NPairIntel(LAMMPS *lmp) : NPair(lmp) { + int ifix = modify->find_fix("package_intel"); + if (ifix < 0) + error->all(FLERR, + "The 'package intel' command is required for /intel styles"); + _fix = static_cast(modify->fix[ifix]); + #ifdef _LMP_INTEL_OFFLOAD + _cop = _fix->coprocessor_number(); + _off_map_stencil = 0; + #endif +} + +/* ---------------------------------------------------------------------- */ + +NPairIntel::~NPairIntel() { + #ifdef _LMP_INTEL_OFFLOAD + if (_off_map_stencil) { + const int * stencil = this->stencil; + #pragma offload_transfer target(mic:_cop) \ + nocopy(stencil:alloc_if(0) free_if(1)) + } + #endif +} + +/* ---------------------------------------------------------------------- + copy needed info from NStencil class to this build class +------------------------------------------------------------------------- */ + +#ifdef _LMP_INTEL_OFFLOAD +void NPairIntel::grow_stencil() +{ + if (_off_map_stencil != stencil) { + if (_off_map_stencil) { + const int * stencil = _off_map_stencil; + #pragma offload_transfer target(mic:_cop) \ + nocopy(stencil:alloc_if(0) free_if(1)) + } + _off_map_stencil = stencil; + const int * stencil = _off_map_stencil; + const int maxstencil = ns->get_maxstencil(); + #pragma offload_transfer target(mic:_cop) \ + in(stencil:length(maxstencil) alloc_if(1) free_if(0)) + } +} +#endif diff --git a/src/USER-INTEL/npair_intel.h b/src/USER-INTEL/npair_intel.h new file mode 100644 index 0000000000..06d5d79cac --- /dev/null +++ b/src/USER-INTEL/npair_intel.h @@ -0,0 +1,117 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_NPAIR_INTEL_H +#define LMP_NPAIR_INTEL_H + +#include "npair.h" +#include "fix_intel.h" + +#if defined(_OPENMP) +#include +#endif + +#ifdef LMP_USE_AVXCD +#include "intel_simd.h" +#endif + +#ifdef OUTER_CHUNK +#include "intel_simd.h" +#endif + +#ifdef _LMP_INTEL_OFFLOAD +#pragma offload_attribute(push,target(mic)) +#endif + +#define ofind_special(which, special, nspecial, i, tag) \ +{ \ + which = 0; \ + const int n1 = nspecial[i * 3]; \ + const int n2 = nspecial[i * 3 + 1]; \ + const int n3 = nspecial[i * 3 + 2]; \ + const tagint *sptr = special + i * maxspecial; \ + for (int s = 0; s < n3; s++) { \ + if (sptr[s] == tag) { \ + if (s < n1) { \ + which = 1; \ + } else if (s < n2) { \ + which = 2; \ + } else { \ + which = 3; \ + } \ + } \ + } \ +} + +#define ominimum_image_check(answer, dx, dy, dz) \ +{ \ + answer = 0; \ + if (xperiodic && fabs(dx) > xprd_half) answer = 1; \ + if (yperiodic && fabs(dy) > yprd_half) answer = 1; \ + if (zperiodic && fabs(dz) > zprd_half) answer = 1; \ +} + +#define dminimum_image_check(answer, dx, dy, dz) \ +{ \ + answer = 0; \ + if (domain->xperiodic && fabs(dx) > domain->xprd_half) answer = 1; \ + if (domain->yperiodic && fabs(dy) > domain->yprd_half) answer = 1; \ + if (domain->zperiodic && fabs(dz) > domain->zprd_half) answer = 1; \ +} + +#ifdef _LMP_INTEL_OFFLOAD +#pragma offload_attribute(pop) +#endif + +namespace LAMMPS_NS { + +class NPairIntel : public NPair { + public: + NPairIntel(class LAMMPS *); + ~NPairIntel(); + + #ifdef _LMP_INTEL_OFFLOAD + void grow_stencil(); + #endif + + protected: + FixIntel *_fix; + + #ifdef _LMP_INTEL_OFFLOAD + int _cop; + int *_off_map_stencil; + #endif +}; + +} + +#endif + +/* ERROR/WARNING messages: + +E: Exclusion lists not yet supported for Intel offload + +Self explanatory. + +E: The 'package intel' command is required for /intel styles + +Self explanatory. + +E: Too many neighbor bins for USER-INTEL package. + +The number of bins used in the stencil to check for neighboring atoms is too +high for the Intel package. Either increase the bin size in the input script +or recompile with a larger setting for INTEL_MAX_STENCIL in intel_preprocess.h. + +*/ + diff --git a/src/USER-OMP/neigh_full_omp.cpp b/src/USER-OMP/neigh_full_omp.cpp deleted file mode 100644 index e61611d41c..0000000000 --- a/src/USER-OMP/neigh_full_omp.cpp +++ /dev/null @@ -1,621 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neighbor_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "comm.h" -#include "domain.h" -#include "group.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - N^2 search for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void Neighbor::full_nsq_omp(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 == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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 &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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - list->gnum = 0; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::full_nsq_ghost_omp(NeighList *list) -{ - const int nlocal = atom->nlocal; - const int nall = nlocal + atom->nghost; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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 &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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - list->gnum = nall - nlocal; -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void Neighbor::full_bin_omp(NeighList *list) -{ - // bin owned & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int nstencil = list->nstencil; - int *stencil = list->stencil; - - // each thread has its own page allocator - MyPage &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 = coord2bin(x[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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - list->gnum = 0; -} - -/* ---------------------------------------------------------------------- - 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 -------------------------------------------------------------------------- */ - -void Neighbor::full_bin_ghost_omp(NeighList *list) -{ - // bin owned & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = atom->nlocal; - const int nall = nlocal + atom->nghost; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_OMP_SETUP(nall); - - int i,j,k,n,itype,jtype,ibin,which,imol,iatom; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int xbin,ybin,zbin,xbin2,ybin2,zbin2; - 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; - int nstencil = list->nstencil; - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - - // each thread has its own page allocator - MyPage &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 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 = coord2bin(x[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) { - 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 (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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - list->gnum = nall - nlocal; -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - multi-type stencil is itype dependent and is distance checked - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void Neighbor::full_multi_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - // each thread has its own page allocator - MyPage &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 - // skip if i,j neighbor cutoff is less than bin distance - // skip i = j - - ibin = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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 (i == j) 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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - list->gnum = 0; -} diff --git a/src/USER-OMP/neigh_gran_omp.cpp b/src/USER-OMP/neigh_gran_omp.cpp deleted file mode 100644 index 82794ff739..0000000000 --- a/src/USER-OMP/neigh_gran_omp.cpp +++ /dev/null @@ -1,618 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include -#include "neighbor.h" -#include "neighbor_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "comm.h" -#include "group.h" -#include "fix_shear_history.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - granular particles - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - 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 Neighbor::granular_nsq_no_newton_omp(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - - FixShearHistory * const fix_history = list->fix_history; - NeighList * listgranhistory = list->listgranhistory; - - NEIGH_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list,listgranhistory) -#endif - NEIGH_OMP_SETUP(nlocal); - - int i,j,m,n,nn,dnum,dnumbytes; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr,*touchptr; - double *shearptr; - - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - 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 &ipage = list->ipage[tid]; - ipage.reset(); - - if (fix_history) { - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage+tid; - dpage_shear = listgranhistory->dpage+tid; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - ipage_touch->reset(); - dpage_shear->reset(); - } - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // loop over remaining atoms, owned and ghost - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - - 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"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - granular particles - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - no shear history is allowed for this option - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests -------------------------------------------------------------------------- */ - -void Neighbor::granular_nsq_newton_omp(NeighList *list) -{ - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_OMP_SETUP(nlocal); - - int i,j,n,itag,jtag; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - 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 &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // loop over remaining atoms, owned and ghost - - 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 (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; - } - } - } - - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - granular particles - binned neighbor list construction with partial Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - 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 Neighbor::granular_bin_no_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - - FixShearHistory * const fix_history = list->fix_history; - NeighList * listgranhistory = list->listgranhistory; - - NEIGH_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list,listgranhistory) -#endif - NEIGH_OMP_SETUP(nlocal); - - int i,j,k,m,n,nn,ibin,dnum,dnumbytes; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr,*touchptr; - double *shearptr; - MyPage *ipage_touch; - MyPage *dpage_shear; - - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - - // loop over each atom, storing neighbors - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - if (fix_history) { - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage+tid; - dpage_shear = listgranhistory->dpage+tid; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - ipage_touch->reset(); - dpage_shear->reset(); - } - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - ibin = coord2bin(x[i]); - - // 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; - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - } - - 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"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - granular particles - binned neighbor list construction with full Newton's 3rd law - no shear history is allowed for this option - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::granular_bin_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_OMP_SETUP(nlocal); - - int i,j,k,n,ibin; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - // loop over each atom, storing neighbors - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // 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; - } - } - - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) neighptr[n++] = j; - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - granular particles - binned neighbor list construction with Newton's 3rd law for triclinic - no shear history is allowed for this option - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::granular_bin_newton_tri_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_OMP_SETUP(nlocal); - - int i,j,k,n,ibin; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr; - - // loop over each atom, storing neighbors - - double **x = atom->x; - double *radius = atom->radius; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // loop over all atoms in bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && j <= i) continue; - } - } - - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/USER-OMP/neigh_half_bin_omp.cpp b/src/USER-OMP/neigh_half_bin_omp.cpp deleted file mode 100644 index 65fa07a48a..0000000000 --- a/src/USER-OMP/neigh_half_bin_omp.cpp +++ /dev/null @@ -1,559 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neighbor_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "comm.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_no_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int nstencil = list->nstencil; - int *stencil = list->stencil; - - // each thread has its own page allocator - MyPage &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 = coord2bin(x[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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_no_newton_ghost_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = atom->nlocal; - const int nall = nlocal + atom->nghost; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int nstencil = list->nstencil; - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - - // each thread has its own page allocator - MyPage &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 = coord2bin(x[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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - list->gnum = nall - atom->nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int nstencil = list->nstencil; - int *stencil = list->stencil; - - // each thread has its own page allocator - MyPage &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) { - 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 = coord2bin(x[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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_newton_tri_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int nstencil = list->nstencil; - int *stencil = list->stencil; - - // each thread has its own page allocator - MyPage &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 bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && 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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/USER-OMP/neigh_half_multi_omp.cpp b/src/USER-OMP/neigh_half_multi_omp.cpp deleted file mode 100644 index cc93bf6367..0000000000 --- a/src/USER-OMP/neigh_half_multi_omp.cpp +++ /dev/null @@ -1,435 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neighbor_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "comm.h" -#include "domain.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_multi_no_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - // each thread has its own page allocator - MyPage &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 = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_multi_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - // each thread has its own page allocator - MyPage &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) { - 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 = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_multi_newton_tri_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - // each thread has its own page allocator - MyPage &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 bins, including self, in stencil - // skip if i,j neighbor cutoff is less than bin distance - // bins below self are excluded from stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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 (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && j <= i) 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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/USER-OMP/neigh_half_nsq_omp.cpp b/src/USER-OMP/neigh_half_nsq_omp.cpp deleted file mode 100644 index ab6e8e5d8c..0000000000 --- a/src/USER-OMP/neigh_half_nsq_omp.cpp +++ /dev/null @@ -1,376 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neighbor_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "comm.h" -#include "domain.h" -#include "group.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_nsq_no_newton_omp(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 == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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 &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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_nsq_no_newton_ghost_omp(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 == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_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 &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) { - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = atom->nlocal; - list->gnum = nall - atom->nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_nsq_newton_omp(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 == 2) ? 1 : 0; - - NEIGH_OMP_INIT; -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_OMP_SETUP(nlocal); - - int i,j,n,itype,jtype,itag,jtag,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 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 &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 - // itag = jtag is possible for long cutoffs that include images of self - - 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 (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; - } - } - - 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"); - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; -} diff --git a/src/USER-OMP/neigh_respa_omp.cpp b/src/USER-OMP/neigh_respa_omp.cpp deleted file mode 100644 index 409090c9ea..0000000000 --- a/src/USER-OMP/neigh_respa_omp.cpp +++ /dev/null @@ -1,972 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neighbor_omp.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "comm.h" -#include "domain.h" -#include "group.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - 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 Neighbor::respa_nsq_no_newton_omp(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 == 2) ? 1 : 0; - - NEIGH_OMP_INIT; - - NeighList *listinner = list->listinner; - NeighList *listmiddle = list->listmiddle; - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list,listinner,listmiddle) -#endif - NEIGH_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 = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = listmiddle->ipage + 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) { - 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"); - } - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - listinner->inum = nlocal; - if (respamiddle) listmiddle->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - multiple respa lists - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests -------------------------------------------------------------------------- */ - -void Neighbor::respa_nsq_newton_omp(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 == 2) ? 1 : 0; - - NEIGH_OMP_INIT; - - NeighList *listinner = list->listinner; - NeighList *listmiddle = list->listmiddle; - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list,listinner,listmiddle) -#endif - NEIGH_OMP_SETUP(nlocal); - - int i,j,n,itype,jtype,itag,jtag,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 = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = listmiddle->ipage + 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(); - } - - 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 - - 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 (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 ((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"); - } - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - listinner->inum = nlocal; - if (respamiddle) listmiddle->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::respa_bin_no_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; - - NeighList *listinner = list->listinner; - NeighList *listmiddle = list->listmiddle; - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list,listinner,listmiddle) -#endif - NEIGH_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 nstencil = list->nstencil; - int *stencil = list->stencil; - - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = listmiddle->ipage + 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 = coord2bin(x[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) { - 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"); - } - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - listinner->inum = nlocal; - if (respamiddle) listmiddle->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::respa_bin_newton_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; - - NeighList *listinner = list->listinner; - NeighList *listmiddle = list->listmiddle; - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list,listinner,listmiddle) -#endif - NEIGH_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 nstencil = list->nstencil; - int *stencil = list->stencil; - - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = listmiddle->ipage + 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) { - 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 = coord2bin(x[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) { - 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"); - } - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - listinner->inum = nlocal; - if (respamiddle) listmiddle->inum = nlocal; -} - -/* ---------------------------------------------------------------------- - multiple respa lists - 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 Neighbor::respa_bin_newton_tri_omp(NeighList *list) -{ - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; - const int molecular = atom->molecular; - const int moltemplate = (molecular == 2) ? 1 : 0; - - NEIGH_OMP_INIT; - - NeighList *listinner = list->listinner; - NeighList *listmiddle = list->listmiddle; - const int respamiddle = list->respamiddle; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list,listinner,listmiddle) -#endif - NEIGH_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 nstencil = list->nstencil; - int *stencil = list->stencil; - - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - if (respamiddle) { - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - } - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - MyPage &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage *ipage_middle; - if (respamiddle) { - ipage_middle = listmiddle->ipage + 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 all atoms in bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && 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) { - 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"); - } - } - NEIGH_OMP_CLOSE; - list->inum = nlocal; - listinner->inum = nlocal; - if (respamiddle) listmiddle->inum = nlocal; -} diff --git a/src/USER-OMP/npair_full_bin_ghost_omp.cpp b/src/USER-OMP/npair_full_bin_ghost_omp.cpp new file mode 100644 index 0000000000..7f7239fe63 --- /dev/null +++ b/src/USER-OMP/npair_full_bin_ghost_omp.cpp @@ -0,0 +1,166 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_bin_ghost_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; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +NPairFullBinGhostOmp::NPairFullBinGhostOmp(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 +------------------------------------------------------------------------- */ + +void NPairFullBinGhostOmp::build(NeighList *list) +{ + const int nlocal = atom->nlocal; + const int nall = nlocal + atom->nghost; + const int molecular = atom->molecular; + const int moltemplate = (molecular == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list) +#endif + NPAIR_OMP_SETUP(nall); + + int i,j,k,n,itype,jtype,ibin,which,imol,iatom; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int xbin,ybin,zbin,xbin2,ybin2,zbin2; + 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 &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 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 = coord2bin(x[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) { + 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 (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; +} diff --git a/src/USER-OMP/npair_full_bin_ghost_omp.h b/src/USER-OMP/npair_full_bin_ghost_omp.h new file mode 100644 index 0000000000..ed1580ac3b --- /dev/null +++ b/src/USER-OMP/npair_full_bin_ghost_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/bin/ghost/omp, + NPairFullBinGhostOmp, + NP_FULL | NP_BIN | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_FULL_BIN_GHOST_OMP_H +#define LMP_NPAIR_FULL_BIN_GHOST_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairFullBinGhostOmp : public NPair { + public: + NPairFullBinGhostOmp(class LAMMPS *); + ~NPairFullBinGhostOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_full_bin_omp.cpp b/src/USER-OMP/npair_full_bin_omp.cpp new file mode 100644 index 0000000000..ad9e48784e --- /dev/null +++ b/src/USER-OMP/npair_full_bin_omp.cpp @@ -0,0 +1,135 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_bin_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; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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 = coord2bin(x[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) { + 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; +} diff --git a/src/USER-OMP/npair_full_bin_omp.h b/src/USER-OMP/npair_full_bin_omp.h new file mode 100644 index 0000000000..5aa17310e2 --- /dev/null +++ b/src/USER-OMP/npair_full_bin_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/bin/omp, + NPairFullBinOmp, + NP_FULL | NP_BIN | NP_OMP | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#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 *); + ~NPairFullBinOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_full_multi_omp.cpp b/src/USER-OMP/npair_full_multi_omp.cpp new file mode 100644 index 0000000000..eb0153d63f --- /dev/null +++ b/src/USER-OMP/npair_full_multi_omp.cpp @@ -0,0 +1,143 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "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; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +NPairFullMultiOmp::NPairFullMultiOmp(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction for all neighbors + multi-type stencil is itype dependent and is distance checked + 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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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 + // skip if i,j neighbor cutoff is less than bin distance + // skip i = j + + ibin = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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 (i == j) 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) { + 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; +} diff --git a/src/USER-OMP/npair_full_multi_omp.h b/src/USER-OMP/npair_full_multi_omp.h new file mode 100644 index 0000000000..36a8d02e28 --- /dev/null +++ b/src/USER-OMP/npair_full_multi_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/multi/omp, + NPairFullMultiOmp, + NP_FULL | NP_MULTI | NP_OMP | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#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 *); + ~NPairFullMultiOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_full_nsq_ghost_omp.cpp b/src/USER-OMP/npair_full_nsq_ghost_omp.cpp new file mode 100644 index 0000000000..b33f76bb22 --- /dev/null +++ b/src/USER-OMP/npair_full_nsq_ghost_omp.cpp @@ -0,0 +1,148 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_nsq_ghost_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; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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) { + 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; +} diff --git a/src/USER-OMP/npair_full_nsq_ghost_omp.h b/src/USER-OMP/npair_full_nsq_ghost_omp.h new file mode 100644 index 0000000000..dbf7f81bcc --- /dev/null +++ b/src/USER-OMP/npair_full_nsq_ghost_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/nsq/ghost/omp, + NPairFullNsqGhostOmp, + NP_FULL | NP_NSQ | NP_GHOST | NP_OMP | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#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 *); + ~NPairFullNsqGhostOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_full_nsq_omp.cpp b/src/USER-OMP/npair_full_nsq_omp.cpp new file mode 100644 index 0000000000..1d0f26d638 --- /dev/null +++ b/src/USER-OMP/npair_full_nsq_omp.cpp @@ -0,0 +1,134 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_nsq_omp.h" +#include "npair_omp.h" +#include "neighbor.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; +using namespace NeighConst; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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) { + 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; +} diff --git a/src/USER-OMP/npair_full_nsq_omp.h b/src/USER-OMP/npair_full_nsq_omp.h new file mode 100644 index 0000000000..2adcb8e1bd --- /dev/null +++ b/src/USER-OMP/npair_full_nsq_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/nsq/omp, + NPairFullNsqOmp, + NP_FULL | NP_NSQ | NP_OMP | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#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 *); + ~NPairFullNsqOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_bin_newtoff_ghost_omp.cpp b/src/USER-OMP/npair_half_bin_newtoff_ghost_omp.cpp new file mode 100644 index 0000000000..e46afebb0d --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newtoff_ghost_omp.cpp @@ -0,0 +1,173 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newtoff_ghost_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; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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 = coord2bin(x[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) { + 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; +} diff --git a/src/USER-OMP/npair_half_bin_newtoff_ghost_omp.h b/src/USER-OMP/npair_half_bin_newtoff_ghost_omp.h new file mode 100644 index 0000000000..4974c407eb --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newtoff_ghost_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newtoff/ghost/omp, + NPairHalfBinNewtoffGhostOmp, + NP_HALF | NP_BIN | NP_NEWTOFF | NP_GHOST | NP_OMP | + NP_ORTHO | NP_TRI) + +#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 *); + ~NPairHalfBinNewtoffGhostOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_bin_newtoff_omp.cpp b/src/USER-OMP/npair_half_bin_newtoff_omp.cpp new file mode 100644 index 0000000000..99698b1d30 --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newtoff_omp.cpp @@ -0,0 +1,138 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_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; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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 = coord2bin(x[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) { + 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; +} diff --git a/src/USER-OMP/npair_half_bin_newtoff_omp.h b/src/USER-OMP/npair_half_bin_newtoff_omp.h new file mode 100644 index 0000000000..06ef355f38 --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newtoff_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newtoff/omp, + NPairHalfBinNewtoffOmp, + NP_HALF | NP_BIN | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI) + +#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 *); + ~NPairHalfBinNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_bin_newton_omp.cpp b/src/USER-OMP/npair_half_bin_newton_omp.cpp new file mode 100644 index 0000000000..33d78fe55a --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newton_omp.cpp @@ -0,0 +1,172 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newton_omp.h" +#include "npair_omp.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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) { + 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 = coord2bin(x[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) { + 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; +} diff --git a/src/USER-OMP/npair_half_bin_newton_omp.h b/src/USER-OMP/npair_half_bin_newton_omp.h new file mode 100644 index 0000000000..f2468f04ad --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newton_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newton/omp, + NPairHalfBinNewtonOmp, + NP_HALF | NP_BIN | NP_NEWTON | NP_OMP | NP_ORTHO) + +#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 *); + ~NPairHalfBinNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_bin_newton_tri_omp.cpp b/src/USER-OMP/npair_half_bin_newton_tri_omp.cpp new file mode 100644 index 0000000000..9eb9612235 --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newton_tri_omp.cpp @@ -0,0 +1,144 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newton_tri_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; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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 bins in stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && 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) { + 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; +} diff --git a/src/USER-OMP/npair_half_bin_newton_tri_omp.h b/src/USER-OMP/npair_half_bin_newton_tri_omp.h new file mode 100644 index 0000000000..f04f16f653 --- /dev/null +++ b/src/USER-OMP/npair_half_bin_newton_tri_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newton/tri/omp, + NPairHalfBinNewtonTriOmp, + NP_HALF | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP) + +#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 *); + ~NPairHalfBinNewtonTriOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_multi_newtoff_omp.cpp b/src/USER-OMP/npair_half_multi_newtoff_omp.cpp new file mode 100644 index 0000000000..37dc805857 --- /dev/null +++ b/src/USER-OMP/npair_half_multi_newtoff_omp.cpp @@ -0,0 +1,145 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "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 + 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 NPairHalfMultiNewtoffOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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 = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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) { + 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; +} diff --git a/src/USER-OMP/npair_half_multi_newtoff_omp.h b/src/USER-OMP/npair_half_multi_newtoff_omp.h new file mode 100644 index 0000000000..a7aebf6579 --- /dev/null +++ b/src/USER-OMP/npair_half_multi_newtoff_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/multi/newtoff/omp, + NPairHalfMultiNewtoffOmp, + NP_HALF | NP_MULTI | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI) + +#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 *); + ~NPairHalfMultiNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_multi_newton_omp.cpp b/src/USER-OMP/npair_half_multi_newton_omp.cpp new file mode 100644 index 0000000000..9719911afa --- /dev/null +++ b/src/USER-OMP/npair_half_multi_newton_omp.cpp @@ -0,0 +1,178 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "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 + 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 NPairHalfMultiNewtonOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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) { + 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 = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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) { + 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; +} diff --git a/src/USER-OMP/npair_half_multi_newton_omp.h b/src/USER-OMP/npair_half_multi_newton_omp.h new file mode 100644 index 0000000000..85df36bb09 --- /dev/null +++ b/src/USER-OMP/npair_half_multi_newton_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/multi/newton/omp, + NPairHalfMultiNewtonOmp, + NP_HALF | NP_MULTI | NP_NEWTON | NP_OMP | NP_ORTHO) + +#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 *); + ~NPairHalfMultiNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_multi_newton_tri_omp.cpp b/src/USER-OMP/npair_half_multi_newton_tri_omp.cpp new file mode 100644 index 0000000000..717a709386 --- /dev/null +++ b/src/USER-OMP/npair_half_multi_newton_tri_omp.cpp @@ -0,0 +1,154 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_multi_newton_tri_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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfMultiNewtonTriOmp::NPairHalfMultiNewtonTriOmp(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 NPairHalfMultiNewtonTriOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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 bins, including self, in stencil + // skip if i,j neighbor cutoff is less than bin distance + // bins below self are excluded from stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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 (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && j <= i) 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) { + 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; +} diff --git a/src/USER-OMP/npair_half_multi_newton_tri_omp.h b/src/USER-OMP/npair_half_multi_newton_tri_omp.h new file mode 100644 index 0000000000..80faf8188f --- /dev/null +++ b/src/USER-OMP/npair_half_multi_newton_tri_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/multi/newton/tri/omp, + NPairHalfMultiNewtonTriOmp, + NP_HALF | NP_MULTI | NP_NEWTON | NP_TRI | NP_OMP) + +#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 *); + ~NPairHalfMultiNewtonTriOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.cpp b/src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.cpp new file mode 100644 index 0000000000..0294658aa0 --- /dev/null +++ b/src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.cpp @@ -0,0 +1,157 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_nsq_newtoff_ghost_omp.h" +#include "npair_omp.h" +#include "neighbor.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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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) { + 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; +} diff --git a/src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.h b/src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.h new file mode 100644 index 0000000000..6b565d9dd8 --- /dev/null +++ b/src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/nsq/newtoff/ghost/omp, + NPairHalfNsqNewtoffGhostOmp, + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_GHOST | NP_OMP | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_OMP_H +#define LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfNsqNewtoffGhostOmp : public NPair { + public: + NPairHalfNsqNewtoffGhostOmp(class LAMMPS *); + ~NPairHalfNsqNewtoffGhostOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_nsq_newtoff_omp.cpp b/src/USER-OMP/npair_half_nsq_newtoff_omp.cpp new file mode 100644 index 0000000000..01da73cf1e --- /dev/null +++ b/src/USER-OMP/npair_half_nsq_newtoff_omp.cpp @@ -0,0 +1,133 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_nsq_newtoff_omp.h" +#include "npair_omp.h" +#include "neighbor.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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) 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 &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) { + 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; +} diff --git a/src/USER-OMP/npair_half_nsq_newtoff_omp.h b/src/USER-OMP/npair_half_nsq_newtoff_omp.h new file mode 100644 index 0000000000..23db92e10a --- /dev/null +++ b/src/USER-OMP/npair_half_nsq_newtoff_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/nsq/newtoff/omp, + NPairHalfNsqNewtoffOmp, + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_OMP | NP_ORTHO | NP_TRI) + +#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 *); + ~NPairHalfNsqNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_nsq_newton_omp.cpp b/src/USER-OMP/npair_half_nsq_newton_omp.cpp new file mode 100644 index 0000000000..3815b1b85b --- /dev/null +++ b/src/USER-OMP/npair_half_nsq_newton_omp.cpp @@ -0,0 +1,151 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_nsq_newton_omp.h" +#include "npair_omp.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i,j,n,itype,jtype,itag,jtag,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 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 &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 + // itag = jtag is possible for long cutoffs that include images of self + + 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 (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; + } + } + + 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; +} diff --git a/src/USER-OMP/npair_half_nsq_newton_omp.h b/src/USER-OMP/npair_half_nsq_newton_omp.h new file mode 100644 index 0000000000..cd40d4217d --- /dev/null +++ b/src/USER-OMP/npair_half_nsq_newton_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/nsq/newton/omp, + NPairHalfNsqNewtonOmp, + NP_HALF | NP_NSQ | NP_NEWTON | NP_OMP | NP_ORTHO | NP_TRI) + +#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 *); + ~NPairHalfNsqNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_respa_bin_newtoff_omp.cpp b/src/USER-OMP/npair_half_respa_bin_newtoff_omp.cpp new file mode 100644 index 0000000000..287f11efa7 --- /dev/null +++ b/src/USER-OMP/npair_half_respa_bin_newtoff_omp.cpp @@ -0,0 +1,204 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_bin_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; + +/* ---------------------------------------------------------------------- */ + +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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; + + NeighList *listinner = list->listinner; + NeighList *listmiddle = list->listmiddle; + const int respamiddle = list->respamiddle; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listinner,listmiddle) +#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 = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + if (respamiddle) { + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + } + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + MyPage &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage *ipage_middle; + if (respamiddle) { + ipage_middle = listmiddle->ipage + 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 = coord2bin(x[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) { + 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; + listinner->inum = nlocal; + if (respamiddle) listmiddle->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_respa_bin_newtoff_omp.h b/src/USER-OMP/npair_half_respa_bin_newtoff_omp.h new file mode 100644 index 0000000000..257aa8fdaa --- /dev/null +++ b/src/USER-OMP/npair_half_respa_bin_newtoff_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/bin/newtoff/omp, + NPairHalfRespaBinNewtoffOmp, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTOFF | NP_OMP | + NP_ORTHO | NP_TRI) + +#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 *); + ~NPairHalfRespaBinNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_respa_bin_newton_omp.cpp b/src/USER-OMP/npair_half_respa_bin_newton_omp.cpp new file mode 100644 index 0000000000..30256bd20d --- /dev/null +++ b/src/USER-OMP/npair_half_respa_bin_newton_omp.cpp @@ -0,0 +1,250 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_bin_newton_omp.h" +#include "neighbor.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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; + + NeighList *listinner = list->listinner; + NeighList *listmiddle = list->listmiddle; + const int respamiddle = list->respamiddle; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listinner,listmiddle) +#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 = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + if (respamiddle) { + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + } + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + MyPage &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage *ipage_middle; + if (respamiddle) { + ipage_middle = listmiddle->ipage + 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) { + 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 = coord2bin(x[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) { + 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; + listinner->inum = nlocal; + if (respamiddle) listmiddle->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_respa_bin_newton_omp.h b/src/USER-OMP/npair_half_respa_bin_newton_omp.h new file mode 100644 index 0000000000..c4bad0aec8 --- /dev/null +++ b/src/USER-OMP/npair_half_respa_bin_newton_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/bin/newton/omp, + NPairHalfRespaBinNewtonOmp, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_OMP | NP_ORTHO) + +#else + +#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_OMP_H +#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfRespaBinNewtonOmp : public NPair { + public: + NPairHalfRespaBinNewtonOmp(class LAMMPS *); + ~NPairHalfRespaBinNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_respa_bin_newton_tri_omp.cpp b/src/USER-OMP/npair_half_respa_bin_newton_tri_omp.cpp new file mode 100644 index 0000000000..27d02000c5 --- /dev/null +++ b/src/USER-OMP/npair_half_respa_bin_newton_tri_omp.cpp @@ -0,0 +1,211 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_bin_newton_tri_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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfRespaBinNewtonTriOmp::NPairHalfRespaBinNewtonTriOmp(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multiple respa lists + 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 NPairHalfRespaBinNewtonTriOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int molecular = atom->molecular; + const int moltemplate = (molecular == 2) ? 1 : 0; + + NPAIR_OMP_INIT; + + NeighList *listinner = list->listinner; + NeighList *listmiddle = list->listmiddle; + const int respamiddle = list->respamiddle; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listinner,listmiddle) +#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 = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + if (respamiddle) { + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + } + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + MyPage &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage *ipage_middle; + if (respamiddle) { + ipage_middle = listmiddle->ipage + 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 all atoms in bins in stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && 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) { + 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_inner.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; + listinner->inum = nlocal; + if (respamiddle) listmiddle->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_respa_bin_newton_tri_omp.h b/src/USER-OMP/npair_half_respa_bin_newton_tri_omp.h new file mode 100644 index 0000000000..ea913f5560 --- /dev/null +++ b/src/USER-OMP/npair_half_respa_bin_newton_tri_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/bin/newton/tri/omp, + NPairHalfRespaBinNewtonTriOmp, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP) + +#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 *); + ~NPairHalfRespaBinNewtonTriOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_respa_nsq_newtoff_omp.cpp b/src/USER-OMP/npair_half_respa_nsq_newtoff_omp.cpp new file mode 100644 index 0000000000..80826ffa42 --- /dev/null +++ b/src/USER-OMP/npair_half_respa_nsq_newtoff_omp.cpp @@ -0,0 +1,198 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_nsq_newtoff_omp.h" +#include "npair_omp.h" +#include "neighbor.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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; + + NeighList *listinner = list->listinner; + NeighList *listmiddle = list->listmiddle; + const int respamiddle = list->respamiddle; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listinner,listmiddle) +#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 = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + if (respamiddle) { + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + } + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + MyPage &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage *ipage_middle; + if (respamiddle) { + ipage_middle = listmiddle->ipage + 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) { + 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; + listinner->inum = nlocal; + if (respamiddle) listmiddle->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_respa_nsq_newtoff_omp.h b/src/USER-OMP/npair_half_respa_nsq_newtoff_omp.h new file mode 100644 index 0000000000..ebd8691635 --- /dev/null +++ b/src/USER-OMP/npair_half_respa_nsq_newtoff_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/nsq/newtoff/omp, + NPairHalfRespaNsqNewtoffOmp, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTOFF | NP_OMP | + NP_ORTHO | NP_TRI) + +#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 *); + ~NPairHalfRespaNsqNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_respa_nsq_newton_omp.cpp b/src/USER-OMP/npair_half_respa_nsq_newton_omp.cpp new file mode 100644 index 0000000000..18319dc1ae --- /dev/null +++ b/src/USER-OMP/npair_half_respa_nsq_newton_omp.cpp @@ -0,0 +1,217 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_nsq_newton_omp.h" +#include "npair_omp.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfRespaNsqNewtonOmp::NPairHalfRespaNsqNewtonOmp(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multiple respa lists + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + if j is ghost only me or other proc adds pair + decision based on itag,jtag tests +------------------------------------------------------------------------- */ + +void NPairHalfRespaNsqNewtonOmp::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 == 2) ? 1 : 0; + + NPAIR_OMP_INIT; + + NeighList *listinner = list->listinner; + NeighList *listmiddle = list->listmiddle; + const int respamiddle = list->respamiddle; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listinner,listmiddle) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i,j,n,itype,jtype,itag,jtag,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 = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + if (respamiddle) { + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + } + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + MyPage &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage *ipage_middle; + if (respamiddle) { + ipage_middle = listmiddle->ipage + 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(); + } + + 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 + + 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 (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 ((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; + listinner->inum = nlocal; + if (respamiddle) listmiddle->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_respa_nsq_newton_omp.h b/src/USER-OMP/npair_half_respa_nsq_newton_omp.h new file mode 100644 index 0000000000..cf39ad8d6e --- /dev/null +++ b/src/USER-OMP/npair_half_respa_nsq_newton_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/nsq/newton/omp, + NPairHalfRespaNsqNewtonOmp, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTON | NP_OMP | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_OMP_H +#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfRespaNsqNewtonOmp : public NPair { + public: + NPairHalfRespaNsqNewtonOmp(class LAMMPS *); + ~NPairHalfRespaNsqNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_size_bin_newtoff_omp.cpp b/src/USER-OMP/npair_half_size_bin_newtoff_omp.cpp new file mode 100644 index 0000000000..89a677806a --- /dev/null +++ b/src/USER-OMP/npair_half_size_bin_newtoff_omp.cpp @@ -0,0 +1,179 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_bin_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 "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeBinNewtoffOmp::NPairHalfSizeBinNewtoffOmp(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + binned neighbor list construction with partial Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + 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 NPairHalfSizeBinNewtoffOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + + FixShearHistory * const fix_history = list->fix_history; + NeighList * listgranhistory = list->listgranhistory; + + NPAIR_OMP_INIT; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listgranhistory) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i,j,k,m,n,nn,ibin,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + MyPage *ipage_touch; + MyPage *dpage_shear; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + + // loop over each atom, storing neighbors + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + 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 &ipage = list->ipage[tid]; + ipage.reset(); + + if (fix_history) { + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage+tid; + dpage_shear = listgranhistory->dpage+tid; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + ibin = coord2bin(x[i]); + + // 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; + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + } + + 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"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_size_bin_newtoff_omp.h b/src/USER-OMP/npair_half_size_bin_newtoff_omp.h new file mode 100644 index 0000000000..7b71aa0ea7 --- /dev/null +++ b/src/USER-OMP/npair_half_size_bin_newtoff_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/bin/newtoff/omp, + NPairHalfSizeBinNewtoffOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_NEWTOFF | NP_OMP | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_OMP_H +#define LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeBinNewtoffOmp : public NPair { + public: + NPairHalfSizeBinNewtoffOmp(class LAMMPS *); + ~NPairHalfSizeBinNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_size_bin_newton_omp.cpp b/src/USER-OMP/npair_half_size_bin_newton_omp.cpp new file mode 100644 index 0000000000..66aa573ca8 --- /dev/null +++ b/src/USER-OMP/npair_half_size_bin_newton_omp.cpp @@ -0,0 +1,227 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_bin_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 "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeBinNewtonOmp::NPairHalfSizeBinNewtonOmp(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + binned neighbor list construction with full Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +void NPairHalfSizeBinNewtonOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + + FixShearHistory * const fix_history = list->fix_history; + NeighList * listgranhistory = list->listgranhistory; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + } + + NPAIR_OMP_INIT; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listgranhistory) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i,j,k,m,n,nn,ibin,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + MyPage *ipage_touch; + MyPage *dpage_shear; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + + // loop over each atom, storing neighbors + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + 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 &ipage = list->ipage[tid]; + ipage.reset(); + + if (fix_history) { + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage+tid; + dpage_shear = listgranhistory->dpage+tid; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // 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; + } + } + + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + + // loop over all atoms in other bins in stencil, store every pair + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + } + + 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"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_size_bin_newton_omp.h b/src/USER-OMP/npair_half_size_bin_newton_omp.h new file mode 100644 index 0000000000..4268ac36a1 --- /dev/null +++ b/src/USER-OMP/npair_half_size_bin_newton_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/bin/newton/omp, + NPairHalfSizeBinNewtonOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_OMP | NP_ORTHO) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_OMP_H +#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeBinNewtonOmp : public NPair { + public: + NPairHalfSizeBinNewtonOmp(class LAMMPS *); + ~NPairHalfSizeBinNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_size_bin_newton_tri_omp.cpp b/src/USER-OMP/npair_half_size_bin_newton_tri_omp.cpp new file mode 100644 index 0000000000..7463a6aba6 --- /dev/null +++ b/src/USER-OMP/npair_half_size_bin_newton_tri_omp.cpp @@ -0,0 +1,121 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_size_bin_newton_tri_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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeBinNewtonTriOmp::NPairHalfSizeBinNewtonTriOmp(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + binned neighbor list construction with Newton's 3rd law for triclinic + no shear history is allowed for this option + each owned atom i checks its own bin and other bins in triclinic stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +void NPairHalfSizeBinNewtonTriOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + + NPAIR_OMP_INIT; +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i,j,k,n,ibin; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr; + + // loop over each atom, storing neighbors + + double **x = atom->x; + double *radius = atom->radius; + 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 &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // loop over all atoms in bins in stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && j <= i) continue; + } + } + + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) 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; +} diff --git a/src/USER-OMP/npair_half_size_bin_newton_tri_omp.h b/src/USER-OMP/npair_half_size_bin_newton_tri_omp.h new file mode 100644 index 0000000000..482ea4c36e --- /dev/null +++ b/src/USER-OMP/npair_half_size_bin_newton_tri_omp.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/bin/newton/tri/omp, + NPairHalfSizeBinNewtonTriOmp, + NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_TRI | NP_OMP) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_OMP_H +#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeBinNewtonTriOmp : public NPair { + public: + NPairHalfSizeBinNewtonTriOmp(class LAMMPS *); + ~NPairHalfSizeBinNewtonTriOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_size_nsq_newtoff_omp.cpp b/src/USER-OMP/npair_half_size_nsq_newtoff_omp.cpp new file mode 100644 index 0000000000..48fc846c52 --- /dev/null +++ b/src/USER-OMP/npair_half_size_nsq_newtoff_omp.cpp @@ -0,0 +1,177 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_nsq_newtoff_omp.h" +#include "npair_omp.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "group.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeNsqNewtoffOmp::NPairHalfSizeNsqNewtoffOmp(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + 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 NPairHalfSizeNsqNewtoffOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0; + + FixShearHistory * const fix_history = list->fix_history; + NeighList * listgranhistory = list->listgranhistory; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + } + + NPAIR_OMP_INIT; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listgranhistory) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i,j,m,n,nn,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + tagint *molecule = atom->molecule; + 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 &ipage = list->ipage[tid]; + ipage.reset(); + + if (fix_history) { + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage+tid; + dpage_shear = listgranhistory->dpage+tid; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // loop over remaining atoms, owned and ghost + + for (j = i+1; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + + 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"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_size_nsq_newtoff_omp.h b/src/USER-OMP/npair_half_size_nsq_newtoff_omp.h new file mode 100644 index 0000000000..793c49335a --- /dev/null +++ b/src/USER-OMP/npair_half_size_nsq_newtoff_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/nsq/newtoff/omp, + NPairHalfSizeNsqNewtoffOmp, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTOFF | NP_OMP | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_OMP_H +#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeNsqNewtoffOmp : public NPair { + public: + NPairHalfSizeNsqNewtoffOmp(class LAMMPS *); + ~NPairHalfSizeNsqNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_half_size_nsq_newton_omp.cpp b/src/USER-OMP/npair_half_size_nsq_newton_omp.cpp new file mode 100644 index 0000000000..086f08a601 --- /dev/null +++ b/src/USER-OMP/npair_half_size_nsq_newton_omp.cpp @@ -0,0 +1,195 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_nsq_newton_omp.h" +#include "npair_omp.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "group.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeNsqNewtonOmp::NPairHalfSizeNsqNewtonOmp(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + pair added to list if atoms i and j are both owned and i < j + if j is ghost only me or other proc adds pair + decision based on itag,jtag tests +------------------------------------------------------------------------- */ + +void NPairHalfSizeNsqNewtonOmp::build(NeighList *list) +{ + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + const int bitmask = (includegroup) ? group->bitmask[includegroup] : 0;; + + FixShearHistory * const fix_history = list->fix_history; + NeighList * listgranhistory = list->listgranhistory; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal+atom->nghost; + } + + NPAIR_OMP_INIT; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list,listgranhistory) +#endif + NPAIR_OMP_SETUP(nlocal); + + int i,j,m,n,nn,itag,jtag,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + tagint *molecule = atom->molecule; + 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 &ipage = list->ipage[tid]; + ipage.reset(); + + if (fix_history) { + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage+tid; + dpage_shear = listgranhistory->dpage+tid; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + itag = tag[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // loop over remaining atoms, owned and ghost + + 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 (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; + } + } + } + + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + + 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"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + NPAIR_OMP_CLOSE; + list->inum = nlocal; +} diff --git a/src/USER-OMP/npair_half_size_nsq_newton_omp.h b/src/USER-OMP/npair_half_size_nsq_newton_omp.h new file mode 100644 index 0000000000..9abdb75db0 --- /dev/null +++ b/src/USER-OMP/npair_half_size_nsq_newton_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/nsq/newton/omp, + NPairHalfSizeNsqNewtonOmp, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTON | NP_OMP | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_OMP_H +#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeNsqNewtonOmp : public NPair { + public: + NPairHalfSizeNsqNewtonOmp(class LAMMPS *); + ~NPairHalfSizeNsqNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/npair_halffull_newtoff_omp.cpp b/src/USER-OMP/npair_halffull_newtoff_omp.cpp new file mode 100644 index 0000000000..947e4e1ad2 --- /dev/null +++ b/src/USER-OMP/npair_halffull_newtoff_omp.cpp @@ -0,0 +1,91 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_halffull_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; + +/* ---------------------------------------------------------------------- */ + +NPairHalffullNewtoffOmp::NPairHalffullNewtoffOmp(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build half list from full list + 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) + works if full list is a skip list +------------------------------------------------------------------------- */ + +void NPairHalffullNewtoffOmp::build(NeighList *list) +{ + const int inum_full = list->listfull->inum; + + NPAIR_OMP_INIT; + +#if defined(_OPENMP) +#pragma omp parallel default(none) shared(list) +#endif + NPAIR_OMP_SETUP(inum_full); + + int i,j,ii,jj,n,jnum,joriginal; + int *neighptr,*jlist; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + int *ilist_full = list->listfull->ilist; + int *numneigh_full = list->listfull->numneigh; + int **firstneigh_full = list->listfull->firstneigh; + + // each thread has its own page allocator + MyPage &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over atoms in full list + + for (ii = ifrom; ii < ito; ii++) { + + n = 0; + neighptr = ipage.vget(); + + // loop over parent full list + + i = ilist_full[ii]; + jlist = firstneigh_full[i]; + jnum = numneigh_full[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (j > i) neighptr[n++] = joriginal; + } + + ilist[ii] = 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 = inum_full; +} diff --git a/src/USER-OMP/npair_halffull_newtoff_omp.h b/src/USER-OMP/npair_halffull_newtoff_omp.h new file mode 100644 index 0000000000..dffef2c3d3 --- /dev/null +++ b/src/USER-OMP/npair_halffull_newtoff_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(halffull/newtoff/omp, + NPairHalffullNewtoffOmp, + NP_HALFFULL | NP_NEWTOFF | NP_OMP | + NP_NSQ | NP_BIN | NP_MULTI | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALFFULL_NEWTOFF_OMP_H +#define LMP_NPAIR_HALFFULL_NEWTOFF_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalffullNewtoffOmp : public NPair { + public: + NPairHalffullNewtoffOmp(class LAMMPS *); + ~NPairHalffullNewtoffOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/neigh_derive_omp.cpp b/src/USER-OMP/npair_halffull_newton_omp.cpp similarity index 61% rename from src/USER-OMP/neigh_derive_omp.cpp rename to src/USER-OMP/npair_halffull_newton_omp.cpp index 8f5fa05e81..6e158d372d 100644 --- a/src/USER-OMP/neigh_derive_omp.cpp +++ b/src/USER-OMP/npair_halffull_newton_omp.cpp @@ -11,77 +11,22 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#include "npair_halffull_newton_omp.h" +#include "npair_omp.h" #include "neighbor.h" -#include "neighbor_omp.h" #include "neigh_list.h" #include "atom.h" -#include "comm.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" #include "my_page.h" #include "error.h" using namespace LAMMPS_NS; -/* ---------------------------------------------------------------------- - build half list from full list - 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) - works if full list is a skip list -------------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- */ -void Neighbor::half_from_full_no_newton_omp(NeighList *list) -{ - const int inum_full = list->listfull->inum; - - NEIGH_OMP_INIT; - -#if defined(_OPENMP) -#pragma omp parallel default(none) shared(list) -#endif - NEIGH_OMP_SETUP(inum_full); - - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - - // each thread has its own page allocator - MyPage &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over atoms in full list - - for (ii = ifrom; ii < ito; ii++) { - - n = 0; - neighptr = ipage.vget(); - - // loop over parent full list - - i = ilist_full[ii]; - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j > i) neighptr[n++] = joriginal; - } - - ilist[ii] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage.vgot(n); - if (ipage.status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - NEIGH_OMP_CLOSE; - list->inum = inum_full; -} +NPairHalffullNewtonOmp::NPairHalffullNewtonOmp(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- build half list from full list @@ -90,15 +35,15 @@ void Neighbor::half_from_full_no_newton_omp(NeighList *list) works if full list is a skip list ------------------------------------------------------------------------- */ -void Neighbor::half_from_full_newton_omp(NeighList *list) +void NPairHalffullNewtonOmp::build(NeighList *list) { const int inum_full = list->listfull->inum; - NEIGH_OMP_INIT; + NPAIR_OMP_INIT; #if defined(_OPENMP) #pragma omp parallel default(none) shared(list) #endif - NEIGH_OMP_SETUP(inum_full); + NPAIR_OMP_SETUP(inum_full); int i,j,ii,jj,n,jnum,joriginal; int *neighptr,*jlist; @@ -157,6 +102,6 @@ void Neighbor::half_from_full_newton_omp(NeighList *list) if (ipage.status()) error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); } - NEIGH_OMP_CLOSE; + NPAIR_OMP_CLOSE; list->inum = inum_full; } diff --git a/src/USER-OMP/npair_halffull_newton_omp.h b/src/USER-OMP/npair_halffull_newton_omp.h new file mode 100644 index 0000000000..f7fc7c1ec7 --- /dev/null +++ b/src/USER-OMP/npair_halffull_newton_omp.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(halffull/newton/omp, + NPairHalffullNewtonOmp, + NP_HALFFULL | NP_NEWTON | NP_OMP | + NP_NSQ | NP_BIN | NP_MULTI | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALFFULL_NEWTON_OMP_H +#define LMP_NPAIR_HALFFULL_NEWTON_OMP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalffullNewtonOmp : public NPair { + public: + NPairHalffullNewtonOmp(class LAMMPS *); + ~NPairHalffullNewtonOmp() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/USER-OMP/neighbor_omp.h b/src/USER-OMP/npair_omp.h similarity index 81% rename from src/USER-OMP/neighbor_omp.h rename to src/USER-OMP/npair_omp.h index 53726109e8..7f7d4d1cc2 100644 --- a/src/USER-OMP/neighbor_omp.h +++ b/src/USER-OMP/npair_omp.h @@ -11,13 +11,14 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ -#ifndef LMP_NEIGHBOR_OMP_H -#define LMP_NEIGHBOR_OMP_H +#ifndef LMP_NPAIR_OMP_H +#define LMP_NPAIR_OMP_H #if defined(_OPENMP) #include #endif +#include "comm.h" #include "modify.h" #include "timer.h" #include "fix_omp.h" @@ -28,13 +29,13 @@ namespace LAMMPS_NS { // these macros hide some ugly and redundant OpenMP related stuff #if defined(_OPENMP) -// make sure we have at least one page for each thread -#define NEIGH_OMP_INIT \ +// get access to number of threads and per-thread data structures via FixOMP +#define NPAIR_OMP_INIT \ const int nthreads = comm->nthreads; \ const int ifix = modify->find_fix("package_omp") // get thread id and then assign each thread a fixed chunk of atoms -#define NEIGH_OMP_SETUP(num) \ +#define NPAIR_OMP_SETUP(num) \ { \ const int tid = omp_get_thread_num(); \ const int idelta = 1 + num/nthreads; \ @@ -45,20 +46,20 @@ namespace LAMMPS_NS { ThrData *thr = fix->get_thr(tid); \ thr->timer(Timer::START); -#define NEIGH_OMP_CLOSE \ +#define NPAIR_OMP_CLOSE \ thr->timer(Timer::NEIGH); \ } #else /* !defined(_OPENMP) */ -#define NEIGH_OMP_INIT +#define NPAIR_OMP_INIT -#define NEIGH_OMP_SETUP(num) \ +#define NPAIR_OMP_SETUP(num) \ const int tid = 0; \ const int ifrom = 0; \ const int ito = num -#define NEIGH_OMP_CLOSE +#define NPAIR_OMP_CLOSE #endif diff --git a/src/USER-OMP/npair_skip_omp.h b/src/USER-OMP/npair_skip_omp.h new file mode 100644 index 0000000000..b909dd7e12 --- /dev/null +++ b/src/USER-OMP/npair_skip_omp.h @@ -0,0 +1,51 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +// There is no benefit from multi-threading for skip lists, so we +// just forward the requests to the corresponding non-omp versions. + +#ifdef NPAIR_CLASS + +NPairStyle(skip/omp, + NPairSkip, + NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP) + +NPairStyle(skip/half/respa/omp, + NPairSkipRespa, + NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP) + +NPairStyle(skip/half/size/omp, + NPairSkipSize, + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP) + +NPairStyle(skip/size/off2on/omp, + NPairSkipSizeOff2on, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI | NP_OMP) + +NPairStyle(skip/size/off2on/oneside/omp, + NPairSkipSizeOff2onOneside, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI | NP_OMP) + +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/accelerator_intel.h b/src/accelerator_intel.h deleted file mode 100644 index fab07989ff..0000000000 --- a/src/accelerator_intel.h +++ /dev/null @@ -1,68 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -// NOTE: this file is *supposed* to be included multiple times - -#ifdef LMP_USER_INTEL - -// true interface to USER-INTEL - -// this part is used inside the neighbor.h header file to -// add functions to the Neighbor class definition - -#ifdef LMP_INSIDE_NEIGHBOR_H - #ifdef LMP_INTEL_OFFLOAD - #ifdef __INTEL_OFFLOAD - template friend class IntelBuffers; - #endif - #endif - - friend class FixIntel; - void *fix_intel; - - template - void bin_atoms(void *, int *, int *); - - template - void hbni(const int, NeighList *, void *, const int, const int, void *, - const int offload_end = 0); - template - void hbnni(const int, NeighList *, void *, const int, const int, void *); - template - void hbnti(const int, NeighList *, void *, const int, const int, void *, - const int offload_end = 0); - template - void fbi(const int, NeighList *, void *, const int, const int, void *, - const int offload_end = 0); - - void half_bin_no_newton_intel(class NeighList *); - void half_bin_newton_intel(class NeighList *); - void half_bin_newton_tri_intel(class NeighList *); - void full_bin_intel(class NeighList *); - -#endif /* !LMP_INSIDE_NEIGHBOR_H */ - -#else /* !LMP_USER_INTEL */ - -// needed for compiling Neighbor class when USER-Intel is not installed - -#ifdef LMP_INSIDE_NEIGHBOR_H - - void half_bin_no_newton_intel(class NeighList *) {} - void half_bin_newton_intel(class NeighList *) {} - void half_bin_newton_tri_intel(class NeighList *) {} - void full_bin_intel(class NeighList *) {} - -#endif - -#endif /* !LMP_USER_INTEL */ diff --git a/src/finish.cpp b/src/finish.cpp index 67e9ce5578..850bc0b019 100644 --- a/src/finish.cpp +++ b/src/finish.cpp @@ -629,22 +629,17 @@ void Finish::end(int flag) // count neighbors in that list for stats purposes // allow it to be Kokkos neigh list as well - for (m = 0; m < neighbor->old_nrequest; m++) { + for (m = 0; m < neighbor->old_nrequest; m++) if ((neighbor->old_requests[m]->half || neighbor->old_requests[m]->gran || neighbor->old_requests[m]->respaouter || neighbor->old_requests[m]->half_from_full) && neighbor->old_requests[m]->skip == 0 && - neighbor->lists[m] && neighbor->lists[m]->numneigh) { - if (!neighbor->lists[m] && lmp->kokkos && - lmp->kokkos->neigh_list_kokkos(m)) break; - else break; - } - } + neighbor->lists[m] && neighbor->lists[m]->numneigh) break; nneigh = 0; if (m < neighbor->old_nrequest) { - if (neighbor->lists[m]) { + if (!neighbor->lists[m]->kokkos) { int inum = neighbor->lists[m]->inum; int *ilist = neighbor->lists[m]->ilist; int *numneigh = neighbor->lists[m]->numneigh; @@ -674,23 +669,19 @@ void Finish::end(int flag) // count neighbors in that list for stats purposes // allow it to be Kokkos neigh list as well - for (m = 0; m < neighbor->old_nrequest; m++) { + for (m = 0; m < neighbor->old_nrequest; m++) if (neighbor->old_requests[m]->full && - neighbor->old_requests[m]->skip == 0) { - if (lmp->kokkos && lmp->kokkos->neigh_list_kokkos(m)) break; - else break; - } - } + neighbor->old_requests[m]->skip == 0) break; nneighfull = 0; if (m < neighbor->old_nrequest) { - if (neighbor->lists[m] && neighbor->lists[m]->numneigh) { + if (!neighbor->lists[m]->kokkos && neighbor->lists[m]->numneigh) { int inum = neighbor->lists[m]->inum; int *ilist = neighbor->lists[m]->ilist; int *numneigh = neighbor->lists[m]->numneigh; for (i = 0; i < inum; i++) nneighfull += numneigh[ilist[i]]; - } else if (!neighbor->lists[m] && lmp->kokkos) + } else if (lmp->kokkos) nneighfull = lmp->kokkos->neigh_count(m); tmp = nneighfull; diff --git a/src/nbin.cpp b/src/nbin.cpp new file mode 100644 index 0000000000..ef8543fdf9 --- /dev/null +++ b/src/nbin.cpp @@ -0,0 +1,143 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nbin.h" +#include "neighbor.h" +#include "domain.h" +#include "update.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NBin::NBin(LAMMPS *lmp) : Pointers(lmp) +{ + last_setup = last_bin = last_bin_memory = -1; + maxbin = maxatom = 0; + binhead = NULL; + bins = NULL; + + // geometry settings + + dimension = domain->dimension; + triclinic = domain->triclinic; +} + +/* ---------------------------------------------------------------------- */ + +NBin::~NBin() +{ + memory->destroy(binhead); + memory->destroy(bins); +} + +/* ---------------------------------------------------------------------- + copy needed info from Neighbor class +------------------------------------------------------------------------- */ + +void NBin::copy_neighbor_info() +{ + includegroup = neighbor->includegroup; + cutneighmin = neighbor->cutneighmin; + cutneighmax = neighbor->cutneighmax; + binsizeflag = neighbor->binsizeflag; + binsize_user = neighbor->binsize_user; + bboxlo = neighbor->bboxlo; + bboxhi = neighbor->bboxhi; +} + +/* ---------------------------------------------------------------------- + setup for bin_atoms() +------------------------------------------------------------------------- */ + +void NBin::bin_atoms_setup(int nall) +{ + // binhead = per-bin vector, mbins in length + // add 1 bin for USER-INTEL package + + if (mbins > maxbin) { + maxbin = mbins; + memory->destroy(binhead); + memory->create(binhead,maxbin,"neigh:binhead"); + last_bin_memory = update->ntimestep; + } + + // bins = per-atom vector + + if (nall > maxatom) { + maxatom = nall; + memory->destroy(bins); + memory->create(bins,maxatom,"neigh:bins"); + last_bin_memory = update->ntimestep; + } + + last_bin = update->ntimestep; +} + +/* ---------------------------------------------------------------------- + convert atom coords into local bin # + for orthogonal, only ghost atoms will have coord >= bboxhi or coord < bboxlo + take special care to insure ghosts are in correct bins even w/ roundoff + hi ghost atoms = nbin,nbin+1,etc + owned atoms = 0 to nbin-1 + lo ghost atoms = -1,-2,etc + this is necessary so that both procs on either side of PBC + treat a pair of atoms straddling the PBC in a consistent way + for triclinic, doesn't matter since stencil & neigh list built differently +------------------------------------------------------------------------- */ + +int NBin::coord2bin(double *x) +{ + int ix,iy,iz; + + if (!ISFINITE(x[0]) || !ISFINITE(x[1]) || !ISFINITE(x[2])) + error->one(FLERR,"Non-numeric positions - simulation unstable"); + + if (x[0] >= bboxhi[0]) + ix = static_cast ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast ((x[0]-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast ((x[1]-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast ((x[2]-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((x[2]-bboxlo[2])*bininvz) - 1; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); +} + +/* ---------------------------------------------------------------------- */ + +bigint NBin::memory_usage() +{ + bigint bytes = 0; + bytes += maxbin*sizeof(int); + bytes += maxatom*sizeof(int); + return bytes; +} diff --git a/src/nbin.h b/src/nbin.h new file mode 100644 index 0000000000..f000df75b0 --- /dev/null +++ b/src/nbin.h @@ -0,0 +1,78 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_NBIN_H +#define LMP_NBIN_H + +#include "pointers.h" + +namespace LAMMPS_NS { + +class NBin : protected Pointers { + public: + int istyle; // 1-N index into binnames + + bigint last_setup,last_bin; // timesteps for last operations performed + bigint last_bin_memory; + + int nbinx,nbiny,nbinz; // # of global bins + int mbins; // # of local bins and offset on this proc + int mbinx,mbiny,mbinz; + int mbinxlo,mbinylo,mbinzlo; + + double binsizex,binsizey,binsizez; // bin sizes and inverse sizes + double bininvx,bininvy,bininvz; + + int *binhead; // index of first atom in each bin + int *bins; // index of next atom in same bin + + NBin(class LAMMPS *); + ~NBin(); + void copy_neighbor_info(); + virtual void bin_atoms_setup(int); + bigint memory_usage(); + + virtual void setup_bins(int) = 0; + virtual void bin_atoms() = 0; + + protected: + + // data from Neighbor class + + int includegroup; + double cutneighmin; + double cutneighmax; + int binsizeflag; + double binsize_user; + double *bboxlo,*bboxhi; + + // data common to all NBin variants + + int dimension; + int triclinic; + + int maxbin; // size of binhead array + int maxatom; // size of bins array + + // methods + + int coord2bin(double *); +}; + +} + +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nbin_standard.cpp b/src/nbin_standard.cpp new file mode 100644 index 0000000000..97257df717 --- /dev/null +++ b/src/nbin_standard.cpp @@ -0,0 +1,232 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nbin_standard.h" +#include "neighbor.h" +#include "atom.h" +#include "group.h" +#include "domain.h" +#include "comm.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +enum{NSQ,BIN,MULTI}; // also in Neighbor + +#define SMALL 1.0e-6 +#define CUT2BIN_RATIO 100 + +/* ---------------------------------------------------------------------- */ + +NBinStandard::NBinStandard(LAMMPS *lmp) : NBin(lmp) {} + +/* ---------------------------------------------------------------------- + setup neighbor binning geometry + bin numbering in each dimension is global: + 0 = 0.0 to binsize, 1 = binsize to 2*binsize, etc + nbin-1,nbin,etc = bbox-binsize to bbox, bbox to bbox+binsize, etc + -1,-2,etc = -binsize to 0.0, -2*binsize to -binsize, etc + code will work for any binsize + since next(xyz) and stencil extend as far as necessary + binsize = 1/2 of cutoff is roughly optimal + for orthogonal boxes: + a dim must be filled exactly by integer # of bins + in periodic, procs on both sides of PBC must see same bin boundary + in non-periodic, coord2bin() still assumes this by use of nbin xyz + for triclinic boxes: + tilted simulation box cannot contain integer # of bins + stencil & neigh list built differently to account for this + mbinlo = lowest global bin any of my ghost atoms could fall into + mbinhi = highest global bin any of my ghost atoms could fall into + mbin = number of bins I need in a dimension +------------------------------------------------------------------------- */ + +void NBinStandard::setup_bins(int style) +{ + last_setup = update->ntimestep; + + // bbox = size of bbox of entire domain + // bsubbox lo/hi = bounding box of my subdomain extended by comm->cutghost + // for triclinic: + // bbox bounds all 8 corners of tilted box + // subdomain is in lamda coords + // include dimension-dependent extension via comm->cutghost + // domain->bbox() converts lamda extent to box coords and computes bbox + + double bbox[3],bsubboxlo[3],bsubboxhi[3]; + double *cutghost = comm->cutghost; + + if (triclinic == 0) { + bsubboxlo[0] = domain->sublo[0] - cutghost[0]; + bsubboxlo[1] = domain->sublo[1] - cutghost[1]; + bsubboxlo[2] = domain->sublo[2] - cutghost[2]; + bsubboxhi[0] = domain->subhi[0] + cutghost[0]; + bsubboxhi[1] = domain->subhi[1] + cutghost[1]; + bsubboxhi[2] = domain->subhi[2] + cutghost[2]; + } else { + double lo[3],hi[3]; + lo[0] = domain->sublo_lamda[0] - cutghost[0]; + lo[1] = domain->sublo_lamda[1] - cutghost[1]; + lo[2] = domain->sublo_lamda[2] - cutghost[2]; + hi[0] = domain->subhi_lamda[0] + cutghost[0]; + hi[1] = domain->subhi_lamda[1] + cutghost[1]; + hi[2] = domain->subhi_lamda[2] + cutghost[2]; + domain->bbox(lo,hi,bsubboxlo,bsubboxhi); + } + + bbox[0] = bboxhi[0] - bboxlo[0]; + bbox[1] = bboxhi[1] - bboxlo[1]; + bbox[2] = bboxhi[2] - bboxlo[2]; + + // optimal bin size is roughly 1/2 the cutoff + // for BIN style, binsize = 1/2 of max neighbor cutoff + // for MULTI style, binsize = 1/2 of min neighbor cutoff + // special case of all cutoffs = 0.0, binsize = box size + + double binsize_optimal; + if (binsizeflag) binsize_optimal = binsize_user; + else if (style == BIN) binsize_optimal = 0.5*cutneighmax; + else binsize_optimal = 0.5*cutneighmin; + if (binsize_optimal == 0.0) binsize_optimal = bbox[0]; + double binsizeinv = 1.0/binsize_optimal; + + // test for too many global bins in any dimension due to huge global domain + + if (bbox[0]*binsizeinv > MAXSMALLINT || bbox[1]*binsizeinv > MAXSMALLINT || + bbox[2]*binsizeinv > MAXSMALLINT) + error->all(FLERR,"Domain too large for neighbor bins"); + + // create actual bins + // always have one bin even if cutoff > bbox + // for 2d, nbinz = 1 + + nbinx = static_cast (bbox[0]*binsizeinv); + nbiny = static_cast (bbox[1]*binsizeinv); + if (dimension == 3) nbinz = static_cast (bbox[2]*binsizeinv); + else nbinz = 1; + + if (nbinx == 0) nbinx = 1; + if (nbiny == 0) nbiny = 1; + if (nbinz == 0) nbinz = 1; + + // compute actual bin size for nbins to fit into box exactly + // error if actual bin size << cutoff, since will create a zillion bins + // this happens when nbin = 1 and box size << cutoff + // typically due to non-periodic, flat system in a particular dim + // in that extreme case, should use NSQ not BIN neighbor style + + binsizex = bbox[0]/nbinx; + binsizey = bbox[1]/nbiny; + binsizez = bbox[2]/nbinz; + + bininvx = 1.0 / binsizex; + bininvy = 1.0 / binsizey; + bininvz = 1.0 / binsizez; + + if (binsize_optimal*bininvx > CUT2BIN_RATIO || + binsize_optimal*bininvy > CUT2BIN_RATIO || + binsize_optimal*bininvz > CUT2BIN_RATIO) + error->all(FLERR,"Cannot use neighbor bins - box size << cutoff"); + + // mbinlo/hi = lowest and highest global bins my ghost atoms could be in + // coord = lowest and highest values of coords for my ghost atoms + // static_cast(-1.5) = -1, so subract additional -1 + // add in SMALL for round-off safety + + int mbinxhi,mbinyhi,mbinzhi; + double coord; + + coord = bsubboxlo[0] - SMALL*bbox[0]; + mbinxlo = static_cast ((coord-bboxlo[0])*bininvx); + if (coord < bboxlo[0]) mbinxlo = mbinxlo - 1; + coord = bsubboxhi[0] + SMALL*bbox[0]; + mbinxhi = static_cast ((coord-bboxlo[0])*bininvx); + + coord = bsubboxlo[1] - SMALL*bbox[1]; + mbinylo = static_cast ((coord-bboxlo[1])*bininvy); + if (coord < bboxlo[1]) mbinylo = mbinylo - 1; + coord = bsubboxhi[1] + SMALL*bbox[1]; + mbinyhi = static_cast ((coord-bboxlo[1])*bininvy); + + if (dimension == 3) { + coord = bsubboxlo[2] - SMALL*bbox[2]; + mbinzlo = static_cast ((coord-bboxlo[2])*bininvz); + if (coord < bboxlo[2]) mbinzlo = mbinzlo - 1; + coord = bsubboxhi[2] + SMALL*bbox[2]; + mbinzhi = static_cast ((coord-bboxlo[2])*bininvz); + } + + // extend bins by 1 to insure stencil extent is included + // for 2d, only 1 bin in z + + mbinxlo = mbinxlo - 1; + mbinxhi = mbinxhi + 1; + mbinx = mbinxhi - mbinxlo + 1; + + mbinylo = mbinylo - 1; + mbinyhi = mbinyhi + 1; + mbiny = mbinyhi - mbinylo + 1; + + if (dimension == 3) { + mbinzlo = mbinzlo - 1; + mbinzhi = mbinzhi + 1; + } else mbinzlo = mbinzhi = 0; + mbinz = mbinzhi - mbinzlo + 1; + + bigint bbin = ((bigint) mbinx) * ((bigint) mbiny) * ((bigint) mbinz) + 1; + if (bbin > MAXSMALLINT) error->one(FLERR,"Too many neighbor bins"); + mbins = bbin; +} + +/* ---------------------------------------------------------------------- + bin owned and ghost atoms +------------------------------------------------------------------------- */ + +void NBinStandard::bin_atoms() +{ + int i,ibin; + + for (i = 0; i < mbins; i++) binhead[i] = -1; + + // bin in reverse order so linked list will be in forward order + // also puts ghost atoms at end of list, which is necessary + + double **x = atom->x; + int *mask = atom->mask; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + if (includegroup) { + int bitmask = group->bitmask[includegroup]; + for (i = nall-1; i >= nlocal; i--) { + if (mask[i] & bitmask) { + ibin = coord2bin(x[i]); + bins[i] = binhead[ibin]; + binhead[ibin] = i; + } + } + for (i = atom->nfirst-1; i >= 0; i--) { + ibin = coord2bin(x[i]); + bins[i] = binhead[ibin]; + binhead[ibin] = i; + } + + } else { + for (i = nall-1; i >= 0; i--) { + ibin = coord2bin(x[i]); + bins[i] = binhead[ibin]; + binhead[ibin] = i; + } + } +} diff --git a/src/nbin_standard.h b/src/nbin_standard.h new file mode 100644 index 0000000000..ca96a4f133 --- /dev/null +++ b/src/nbin_standard.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NBIN_CLASS + +NBinStyle(standard, + NBinStandard, + 0) + +#else + +#ifndef LMP_NBIN_STANDARD_H +#define LMP_NBIN_STANDARD_H + +#include "nbin.h" + +namespace LAMMPS_NS { + +class NBinStandard : public NBin { + public: + NBinStandard(class LAMMPS *); + ~NBinStandard() {} + void setup_bins(int); + void bin_atoms(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/neigh_bond.cpp b/src/neigh_bond.cpp deleted file mode 100644 index c85407c45b..0000000000 --- a/src/neigh_bond.cpp +++ /dev/null @@ -1,1028 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "force.h" -#include "update.h" -#include "domain.h" -#include "output.h" -#include "thermo.h" -#include "memory.h" -#include "error.h" - -using namespace LAMMPS_NS; - -#define BONDDELTA 10000 - -enum{IGNORE,WARN,ERROR}; // same as thermo.cpp - -// bondlist, anglelist, dihedrallist, improperlist -// no longer store atom->map() of the bond partners -// instead store domain->closest_image() of the bond partners of atom I -// this enables distances between list atoms to be calculated -// w/out invoking domain->minimium_image(), e.g. in bond->compute() - -/* ---------------------------------------------------------------------- */ - -void Neighbor::bond_all() -{ - int i,m,atom1; - - int nlocal = atom->nlocal; - int *num_bond = atom->num_bond; - tagint **bond_atom = atom->bond_atom; - int **bond_type = atom->bond_type; - tagint *tag = atom->tag; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nbondlist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_bond[i]; m++) { - atom1 = atom->map(bond_atom[i][m]); - if (atom1 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - tag[i],bond_atom[i][m],me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - if (newton_bond || i < atom1) { - if (nbondlist == maxbond) { - maxbond += BONDDELTA; - memory->grow(bondlist,maxbond,3,"neighbor:bondlist"); - } - bondlist[nbondlist][0] = i; - bondlist[nbondlist][1] = atom1; - bondlist[nbondlist][2] = bond_type[i][m]; - nbondlist++; - } - } - - if (cluster_check) bond_check(); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::bond_template() -{ - int i,m,atom1; - int imol,iatom; - tagint tagprev; - int *num_bond; - tagint **bond_atom; - int **bond_type; - - Molecule **onemols = atom->avec->onemols; - - tagint *tag = atom->tag; - int *molindex = atom->molindex; - int *molatom = atom->molatom; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nbondlist = 0; - - for (i = 0; i < nlocal; i++) { - if (molindex[i] < 0) continue; - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - num_bond = onemols[imol]->num_bond; - bond_atom = onemols[imol]->bond_atom; - bond_type = onemols[imol]->bond_type; - - for (m = 0; m < num_bond[iatom]; m++) { - if (bond_type[iatom][m] <= 0) continue; - atom1 = atom->map(bond_atom[iatom][m]+tagprev); - if (atom1 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - tag[i],bond_atom[iatom][m]+tagprev,me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - if (newton_bond || i < atom1) { - if (nbondlist == maxbond) { - maxbond += BONDDELTA; - memory->grow(bondlist,maxbond,3,"neighbor:bondlist"); - } - bondlist[nbondlist][0] = i; - bondlist[nbondlist][1] = atom1; - bondlist[nbondlist][2] = bond_type[iatom][m]; - nbondlist++; - } - } - } - - if (cluster_check) bond_check(); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::bond_partial() -{ - int i,m,atom1; - - int nlocal = atom->nlocal; - int *num_bond = atom->num_bond; - tagint **bond_atom = atom->bond_atom; - int **bond_type = atom->bond_type; - tagint *tag = atom->tag; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nbondlist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_bond[i]; m++) { - if (bond_type[i][m] <= 0) continue; - atom1 = atom->map(bond_atom[i][m]); - if (atom1 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - tag[i],bond_atom[i][m],me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - if (newton_bond || i < atom1) { - if (nbondlist == maxbond) { - maxbond += BONDDELTA; - memory->grow(bondlist,maxbond,3,"neighbor:bondlist"); - } - bondlist[nbondlist][0] = i; - bondlist[nbondlist][1] = atom1; - bondlist[nbondlist][2] = bond_type[i][m]; - nbondlist++; - } - } - - if (cluster_check) bond_check(); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::bond_check() -{ - int i,j; - double dx,dy,dz,dxstart,dystart,dzstart; - - double **x = atom->x; - int flag = 0; - - for (int m = 0; m < nbondlist; m++) { - i = bondlist[m][0]; - j = bondlist[m][1]; - dxstart = dx = x[i][0] - x[j][0]; - dystart = dy = x[i][1] - x[j][1]; - dzstart = dz = x[i][2] - x[j][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - } - - int flag_all; - MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all(FLERR,"Bond extent > half of periodic box length"); -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::angle_all() -{ - int i,m,atom1,atom2,atom3; - - int nlocal = atom->nlocal; - 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 newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nanglelist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_angle[i]; m++) { - atom1 = atom->map(angle_atom1[i][m]); - atom2 = atom->map(angle_atom2[i][m]); - atom3 = atom->map(angle_atom3[i][m]); - if (atom1 == -1 || atom2 == -1 || atom3 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Angle atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m], - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { - if (nanglelist == maxangle) { - maxangle += BONDDELTA; - memory->grow(anglelist,maxangle,4,"neighbor:anglelist"); - } - anglelist[nanglelist][0] = atom1; - anglelist[nanglelist][1] = atom2; - anglelist[nanglelist][2] = atom3; - anglelist[nanglelist][3] = angle_type[i][m]; - nanglelist++; - } - } - - if (cluster_check) angle_check(); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::angle_template() -{ - int i,m,atom1,atom2,atom3; - int imol,iatom; - tagint tagprev; - int *num_angle; - tagint **angle_atom1,**angle_atom2,**angle_atom3; - int **angle_type; - - Molecule **onemols = atom->avec->onemols; - - tagint *tag = atom->tag; - int *molindex = atom->molindex; - int *molatom = atom->molatom; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nanglelist = 0; - - for (i = 0; i < nlocal; i++) { - if (molindex[i] < 0) continue; - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - num_angle = onemols[imol]->num_angle; - angle_atom1 = onemols[imol]->angle_atom1; - angle_atom2 = onemols[imol]->angle_atom2; - angle_atom3 = onemols[imol]->angle_atom3; - angle_type = onemols[imol]->angle_type; - - for (m = 0; m < num_angle[iatom]; m++) { - if (angle_type[iatom][m] <= 0) continue; - atom1 = atom->map(angle_atom1[iatom][m]+tagprev); - atom2 = atom->map(angle_atom2[iatom][m]+tagprev); - atom3 = atom->map(angle_atom3[iatom][m]+tagprev); - if (atom1 == -1 || atom2 == -1 || atom3 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Angle atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - angle_atom1[iatom][m]+tagprev,angle_atom2[iatom][m]+tagprev, - angle_atom3[iatom][m]+tagprev, - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { - if (nanglelist == maxangle) { - maxangle += BONDDELTA; - memory->grow(anglelist,maxangle,4,"neighbor:anglelist"); - } - anglelist[nanglelist][0] = atom1; - anglelist[nanglelist][1] = atom2; - anglelist[nanglelist][2] = atom3; - anglelist[nanglelist][3] = angle_type[iatom][m]; - nanglelist++; - } - } - } - - if (cluster_check) angle_check(); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::angle_partial() -{ - int i,m,atom1,atom2,atom3; - - int nlocal = atom->nlocal; - 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 newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nanglelist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_angle[i]; m++) { - if (angle_type[i][m] <= 0) continue; - atom1 = atom->map(angle_atom1[i][m]); - atom2 = atom->map(angle_atom2[i][m]); - atom3 = atom->map(angle_atom3[i][m]); - if (atom1 == -1 || atom2 == -1 || atom3 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Angle atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m], - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { - if (nanglelist == maxangle) { - maxangle += BONDDELTA; - memory->grow(anglelist,maxangle,4,"neighbor:anglelist"); - } - anglelist[nanglelist][0] = atom1; - anglelist[nanglelist][1] = atom2; - anglelist[nanglelist][2] = atom3; - anglelist[nanglelist][3] = angle_type[i][m]; - nanglelist++; - } - } - - if (cluster_check) angle_check(); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::angle_check() -{ - int i,j,k; - double dx,dy,dz,dxstart,dystart,dzstart; - - double **x = atom->x; - int flag = 0; - - // check all 3 distances - // in case angle potential computes any of them - - for (int m = 0; m < nanglelist; m++) { - i = anglelist[m][0]; - j = anglelist[m][1]; - k = anglelist[m][2]; - dxstart = dx = x[i][0] - x[j][0]; - dystart = dy = x[i][1] - x[j][1]; - dzstart = dz = x[i][2] - x[j][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - dxstart = dx = x[i][0] - x[k][0]; - dystart = dy = x[i][1] - x[k][1]; - dzstart = dz = x[i][2] - x[k][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - dxstart = dx = x[j][0] - x[k][0]; - dystart = dy = x[j][1] - x[k][1]; - dzstart = dz = x[j][2] - x[k][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - } - - int flag_all; - MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) error->all(FLERR,"Angle extent > half of periodic box length"); -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::dihedral_all() -{ - int i,m,atom1,atom2,atom3,atom4; - - int nlocal = atom->nlocal; - 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 **dihedral_type = atom->dihedral_type; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - ndihedrallist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_dihedral[i]; m++) { - atom1 = atom->map(dihedral_atom1[i][m]); - atom2 = atom->map(dihedral_atom2[i][m]); - atom3 = atom->map(dihedral_atom3[i][m]); - atom4 = atom->map(dihedral_atom4[i][m]); - if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Dihedral atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " - TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - dihedral_atom1[i][m],dihedral_atom2[i][m], - dihedral_atom3[i][m],dihedral_atom4[i][m], - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - atom4 = domain->closest_image(i,atom4); - if (newton_bond || - (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { - if (ndihedrallist == maxdihedral) { - maxdihedral += BONDDELTA; - memory->grow(dihedrallist,maxdihedral,5,"neighbor:dihedrallist"); - } - dihedrallist[ndihedrallist][0] = atom1; - dihedrallist[ndihedrallist][1] = atom2; - dihedrallist[ndihedrallist][2] = atom3; - dihedrallist[ndihedrallist][3] = atom4; - dihedrallist[ndihedrallist][4] = dihedral_type[i][m]; - ndihedrallist++; - } - } - - if (cluster_check) dihedral_check(ndihedrallist,dihedrallist); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::dihedral_template() -{ - int i,m,atom1,atom2,atom3,atom4; - int imol,iatom; - tagint tagprev; - int *num_dihedral; - tagint **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4; - int **dihedral_type; - - Molecule **onemols = atom->avec->onemols; - - tagint *tag = atom->tag; - int *molindex = atom->molindex; - int *molatom = atom->molatom; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - ndihedrallist = 0; - - for (i = 0; i < nlocal; i++) { - if (molindex[i] < 0) continue; - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - num_dihedral = onemols[imol]->num_dihedral; - dihedral_atom1 = onemols[imol]->dihedral_atom1; - dihedral_atom2 = onemols[imol]->dihedral_atom2; - dihedral_atom3 = onemols[imol]->dihedral_atom3; - dihedral_atom4 = onemols[imol]->dihedral_atom4; - dihedral_type = onemols[imol]->dihedral_type; - - for (m = 0; m < num_dihedral[iatom]; m++) { - atom1 = atom->map(dihedral_atom1[iatom][m]+tagprev); - atom2 = atom->map(dihedral_atom2[iatom][m]+tagprev); - atom3 = atom->map(dihedral_atom3[iatom][m]+tagprev); - atom4 = atom->map(dihedral_atom4[iatom][m]+tagprev); - if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Dihedral atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " - TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - dihedral_atom1[iatom][m]+tagprev, - dihedral_atom2[iatom][m]+tagprev, - dihedral_atom3[iatom][m]+tagprev, - dihedral_atom4[iatom][m]+tagprev, - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - atom4 = domain->closest_image(i,atom4); - if (newton_bond || - (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { - if (ndihedrallist == maxdihedral) { - maxdihedral += BONDDELTA; - memory->grow(dihedrallist,maxdihedral,5,"neighbor:dihedrallist"); - } - dihedrallist[ndihedrallist][0] = atom1; - dihedrallist[ndihedrallist][1] = atom2; - dihedrallist[ndihedrallist][2] = atom3; - dihedrallist[ndihedrallist][3] = atom4; - dihedrallist[ndihedrallist][4] = dihedral_type[iatom][m]; - ndihedrallist++; - } - } - } - - if (cluster_check) dihedral_check(ndihedrallist,dihedrallist); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::dihedral_partial() -{ - int i,m,atom1,atom2,atom3,atom4; - - int nlocal = atom->nlocal; - 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 **dihedral_type = atom->dihedral_type; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - ndihedrallist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_dihedral[i]; m++) { - if (dihedral_type[i][m] <= 0) continue; - atom1 = atom->map(dihedral_atom1[i][m]); - atom2 = atom->map(dihedral_atom2[i][m]); - atom3 = atom->map(dihedral_atom3[i][m]); - atom4 = atom->map(dihedral_atom4[i][m]); - if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Dihedral atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " - TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - dihedral_atom1[i][m],dihedral_atom2[i][m], - dihedral_atom3[i][m],dihedral_atom4[i][m], - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - atom4 = domain->closest_image(i,atom4); - if (newton_bond || - (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { - if (ndihedrallist == maxdihedral) { - maxdihedral += BONDDELTA; - memory->grow(dihedrallist,maxdihedral,5,"neighbor:dihedrallist"); - } - dihedrallist[ndihedrallist][0] = atom1; - dihedrallist[ndihedrallist][1] = atom2; - dihedrallist[ndihedrallist][2] = atom3; - dihedrallist[ndihedrallist][3] = atom4; - dihedrallist[ndihedrallist][4] = dihedral_type[i][m]; - ndihedrallist++; - } - } - - if (cluster_check) dihedral_check(ndihedrallist,dihedrallist); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::dihedral_check(int nlist, int **list) -{ - int i,j,k,l; - double dx,dy,dz,dxstart,dystart,dzstart; - - double **x = atom->x; - int flag = 0; - - // check all 6 distances - // in case dihedral/improper potential computes any of them - - for (int m = 0; m < nlist; m++) { - i = list[m][0]; - j = list[m][1]; - k = list[m][2]; - l = list[m][3]; - dxstart = dx = x[i][0] - x[j][0]; - dystart = dy = x[i][1] - x[j][1]; - dzstart = dz = x[i][2] - x[j][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - dxstart = dx = x[i][0] - x[k][0]; - dystart = dy = x[i][1] - x[k][1]; - dzstart = dz = x[i][2] - x[k][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - dxstart = dx = x[i][0] - x[l][0]; - dystart = dy = x[i][1] - x[l][1]; - dzstart = dz = x[i][2] - x[l][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - dxstart = dx = x[j][0] - x[k][0]; - dystart = dy = x[j][1] - x[k][1]; - dzstart = dz = x[j][2] - x[k][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - dxstart = dx = x[j][0] - x[l][0]; - dystart = dy = x[j][1] - x[l][1]; - dzstart = dz = x[j][2] - x[l][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - dxstart = dx = x[k][0] - x[l][0]; - dystart = dy = x[k][1] - x[l][1]; - dzstart = dz = x[k][2] - x[l][2]; - domain->minimum_image(dx,dy,dz); - if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; - } - - int flag_all; - MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); - if (flag_all) - error->all(FLERR,"Dihedral/improper extent > half of periodic box length"); -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::improper_all() -{ - int i,m,atom1,atom2,atom3,atom4; - - int nlocal = atom->nlocal; - int *num_improper = atom->num_improper; - tagint **improper_atom1 = atom->improper_atom1; - tagint **improper_atom2 = atom->improper_atom2; - tagint **improper_atom3 = atom->improper_atom3; - tagint **improper_atom4 = atom->improper_atom4; - int **improper_type = atom->improper_type; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nimproperlist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_improper[i]; m++) { - atom1 = atom->map(improper_atom1[i][m]); - atom2 = atom->map(improper_atom2[i][m]); - atom3 = atom->map(improper_atom3[i][m]); - atom4 = atom->map(improper_atom4[i][m]); - if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Improper atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " - TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - improper_atom1[i][m],improper_atom2[i][m], - improper_atom3[i][m],improper_atom4[i][m], - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - atom4 = domain-> closest_image(i,atom4); - if (newton_bond || - (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { - if (nimproperlist == maximproper) { - maximproper += BONDDELTA; - memory->grow(improperlist,maximproper,5,"neighbor:improperlist"); - } - improperlist[nimproperlist][0] = atom1; - improperlist[nimproperlist][1] = atom2; - improperlist[nimproperlist][2] = atom3; - improperlist[nimproperlist][3] = atom4; - improperlist[nimproperlist][4] = improper_type[i][m]; - nimproperlist++; - } - } - - if (cluster_check) dihedral_check(nimproperlist,improperlist); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::improper_template() -{ - int i,m,atom1,atom2,atom3,atom4; - int imol,iatom; - tagint tagprev; - int *num_improper; - tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4; - int **improper_type; - - Molecule **onemols = atom->avec->onemols; - - tagint *tag = atom->tag; - int *molindex = atom->molindex; - int *molatom = atom->molatom; - int nlocal = atom->nlocal; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nimproperlist = 0; - - for (i = 0; i < nlocal; i++) { - if (molindex[i] < 0) continue; - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - num_improper = onemols[imol]->num_improper; - improper_atom1 = onemols[imol]->improper_atom1; - improper_atom2 = onemols[imol]->improper_atom2; - improper_atom3 = onemols[imol]->improper_atom3; - improper_atom4 = onemols[imol]->improper_atom4; - improper_type = onemols[imol]->improper_type; - - for (m = 0; m < num_improper[iatom]; m++) { - atom1 = atom->map(improper_atom1[iatom][m]+tagprev); - atom2 = atom->map(improper_atom2[iatom][m]+tagprev); - atom3 = atom->map(improper_atom3[iatom][m]+tagprev); - atom4 = atom->map(improper_atom4[iatom][m]+tagprev); - if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Improper atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " - TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - improper_atom1[iatom][m]+tagprev, - improper_atom2[iatom][m]+tagprev, - improper_atom3[iatom][m]+tagprev, - improper_atom4[iatom][m]+tagprev, - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - atom4 = domain-> closest_image(i,atom4); - if (newton_bond || - (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { - if (nimproperlist == maximproper) { - maximproper += BONDDELTA; - memory->grow(improperlist,maximproper,5,"neighbor:improperlist"); - } - improperlist[nimproperlist][0] = atom1; - improperlist[nimproperlist][1] = atom2; - improperlist[nimproperlist][2] = atom3; - improperlist[nimproperlist][3] = atom4; - improperlist[nimproperlist][4] = improper_type[iatom][m]; - nimproperlist++; - } - } - } - - if (cluster_check) dihedral_check(nimproperlist,improperlist); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::improper_partial() -{ - int i,m,atom1,atom2,atom3,atom4; - - int nlocal = atom->nlocal; - int *num_improper = atom->num_improper; - tagint **improper_atom1 = atom->improper_atom1; - tagint **improper_atom2 = atom->improper_atom2; - tagint **improper_atom3 = atom->improper_atom3; - tagint **improper_atom4 = atom->improper_atom4; - int **improper_type = atom->improper_type; - int newton_bond = force->newton_bond; - - int lostbond = output->thermo->lostbond; - int nmissing = 0; - nimproperlist = 0; - - for (i = 0; i < nlocal; i++) - for (m = 0; m < num_improper[i]; m++) { - if (improper_type[i][m] <= 0) continue; - atom1 = atom->map(improper_atom1[i][m]); - atom2 = atom->map(improper_atom2[i][m]); - atom3 = atom->map(improper_atom3[i][m]); - atom4 = atom->map(improper_atom4[i][m]); - if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { - nmissing++; - if (lostbond == ERROR) { - char str[128]; - sprintf(str,"Improper atoms " - TAGINT_FORMAT " " TAGINT_FORMAT " " - TAGINT_FORMAT " " TAGINT_FORMAT - " missing on proc %d at step " BIGINT_FORMAT, - improper_atom1[i][m],improper_atom2[i][m], - improper_atom3[i][m],improper_atom4[i][m], - me,update->ntimestep); - error->one(FLERR,str); - } - continue; - } - atom1 = domain->closest_image(i,atom1); - atom2 = domain->closest_image(i,atom2); - atom3 = domain->closest_image(i,atom3); - atom4 = domain->closest_image(i,atom4); - if (newton_bond || - (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { - if (nimproperlist == maximproper) { - maximproper += BONDDELTA; - memory->grow(improperlist,maximproper,5,"neighbor:improperlist"); - } - improperlist[nimproperlist][0] = atom1; - improperlist[nimproperlist][1] = atom2; - improperlist[nimproperlist][2] = atom3; - improperlist[nimproperlist][3] = atom4; - improperlist[nimproperlist][4] = improper_type[i][m]; - nimproperlist++; - } - } - - if (cluster_check) dihedral_check(nimproperlist,improperlist); - if (lostbond == IGNORE) return; - - int all; - MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); - if (all) { - char str[128]; - sprintf(str, - "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); - if (me == 0) error->warning(FLERR,str); - } -} diff --git a/src/neigh_bond.h b/src/neigh_bond.h deleted file mode 100644 index 894c4aebae..0000000000 --- a/src/neigh_bond.h +++ /dev/null @@ -1,88 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ERROR/WARNING messages: - -E: Bond atoms %d %d missing on proc %d at step %ld - -The 2nd atom needed to compute a particular bond is missing on this -processor. Typically this is because the pairwise cutoff is set too -short or the bond has blown apart and an atom is too far away. - -W: Bond atoms missing at step %ld - -The 2nd atom needed to compute a particular bond is missing on this -processor. Typically this is because the pairwise cutoff is set too -short or the bond has blown apart and an atom is too far away. - -E: Bond extent > half of periodic box length - -This error was detected by the neigh_modify check yes setting. It is -an error because the bond atoms are so far apart it is ambiguous how -it should be defined. - -E: Angle atoms %d %d %d missing on proc %d at step %ld - -One or more of 3 atoms needed to compute a particular angle are -missing on this processor. Typically this is because the pairwise -cutoff is set too short or the angle has blown apart and an atom is -too far away. - -W: Angle atoms missing at step %ld - -One or more of 3 atoms needed to compute a particular angle are -missing on this processor. Typically this is because the pairwise -cutoff is set too short or the angle has blown apart and an atom is -too far away. - -E: Angle extent > half of periodic box length - -This error was detected by the neigh_modify check yes setting. It is -an error because the angle atoms are so far apart it is ambiguous how -it should be defined. - -E: Dihedral atoms %d %d %d %d missing on proc %d at step %ld - -One or more of 4 atoms needed to compute a particular dihedral are -missing on this processor. Typically this is because the pairwise -cutoff is set too short or the dihedral has blown apart and an atom is -too far away. - -W: Dihedral atoms missing at step %ld - -One or more of 4 atoms needed to compute a particular dihedral are -missing on this processor. Typically this is because the pairwise -cutoff is set too short or the dihedral has blown apart and an atom is -too far away. - -E: Dihedral/improper extent > half of periodic box length - -This error was detected by the neigh_modify check yes setting. It is -an error because the dihedral atoms are so far apart it is ambiguous -how it should be defined. - -E: Improper atoms %d %d %d %d missing on proc %d at step %ld - -One or more of 4 atoms needed to compute a particular improper are -missing on this processor. Typically this is because the pairwise -cutoff is set too short or the improper has blown apart and an atom is -too far away. - -W: Improper atoms missing at step %ld - -One or more of 4 atoms needed to compute a particular improper are -missing on this processor. Typically this is because the pairwise -cutoff is set too short or the improper has blown apart and an atom is -too far away. - -*/ diff --git a/src/neigh_derive.cpp b/src/neigh_derive.cpp deleted file mode 100644 index d53ff30fc5..0000000000 --- a/src/neigh_derive.cpp +++ /dev/null @@ -1,843 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "domain.h" -#include "fix_shear_history.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - build half list from full list - 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) - works if full list is a skip list -------------------------------------------------------------------------- */ - -void Neighbor::half_from_full_no_newton(NeighList *list) -{ - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - - int inum = 0; - ipage->reset(); - - // loop over atoms in full list - - for (ii = 0; ii < inum_full; ii++) { - n = 0; - neighptr = ipage->vget(); - - // loop over parent full list - - i = ilist_full[ii]; - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j > i) neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 -------------------------------------------------------------------------- */ - -void Neighbor::half_from_full_newton(NeighList *list) -{ - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - double xtmp,ytmp,ztmp; - - double **x = atom->x; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - - int inum = 0; - ipage->reset(); - - // loop over parent full list - - for (ii = 0; ii < inum_full; ii++) { - n = 0; - neighptr = ipage->vget(); - - i = ilist_full[ii]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - - // loop over full neighbor list - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j < nlocal) { - if (i > j) 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; - } - } - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - this is for half and full lists - if ghostflag, also store neighbors of ghost atoms & set inum,gnum correctly -------------------------------------------------------------------------- */ - -void Neighbor::skip_from(NeighList *list) -{ - int i,j,ii,jj,n,itype,jnum,joriginal; - int *neighptr,*jlist; - - int *type = atom->type; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int num_skip = list->listskip->inum; - if (list->ghostflag) num_skip += list->listskip->gnum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - int inum = 0; - ipage->reset(); - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < num_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - n = 0; - neighptr = ipage->vget(); - - // loop over parent non-skip list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - if (list->ghostflag) { - int num = 0; - for (i = 0; i < inum; i++) - if (ilist[i] < nlocal) num++; - else break; - list->inum = num; - list->gnum = inum - num; - } -} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - if list requests it, preserve shear history via fix shear/history -------------------------------------------------------------------------- */ - -void Neighbor::skip_from_granular(NeighList *list) -{ - int i,j,ii,jj,m,n,nn,itype,jnum,joriginal,dnum,dnumbytes; - tagint jtag; - int *neighptr,*jlist,*touchptr; - double *shearptr; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - tagint *tag = atom->tag; - int *type = atom->type; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nlocal + atom->nghost; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - n = 0; - neighptr = ipage->vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - // loop over parent non-skip granular list and optionally its history info - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - neighptr[n] = joriginal; - - // no numeric test for current touch - // just use FSH partner list to infer it - // would require distance calculation for spheres - // more complex calculation for surfs - - if (fix_history) { - jtag = tag[j]; - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == jtag) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - parent non-skip list used newton off, this skip list is newton on - if list requests it, preserve shear history via fix shear/history -------------------------------------------------------------------------- */ - -void Neighbor::skip_from_granular_off2on(NeighList *list) -{ - int i,j,ii,jj,m,n,nn,itype,jnum,joriginal,dnum,dnumbytes; - tagint itag,jtag; - int *neighptr,*jlist,*touchptr; - double *shearptr; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - tagint *tag = atom->tag; - int *type = atom->type; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nlocal + atom->nghost; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - itag = tag[i]; - - n = 0; - neighptr = ipage->vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - // loop over parent non-skip granular list and optionally its history info - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - // only keep I,J when J = ghost if Itag < Jtag - - jtag = tag[j]; - if (j >= nlocal && jtag < itag) continue; - - neighptr[n] = joriginal; - - // no numeric test for current touch - // just use FSH partner list to infer it - // would require distance calculation for spheres - // more complex calculation for surfs - - if (fix_history) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == jtag) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - parent non-skip list used newton off and was not onesided, - this skip list is newton on and onesided - if list requests it, preserve shear history via fix shear/history -------------------------------------------------------------------------- */ - -void Neighbor::skip_from_granular_off2on_onesided(NeighList *list) -{ - int i,j,ii,jj,m,n,nn,itype,jnum,joriginal,flip,dnum,dnumbytes,tmp; - tagint jtag; - int *surf,*jlist; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - tagint *tag = atom->tag; - int *type = atom->type; - int nlocal = atom->nlocal; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - if (domain->dimension == 2) surf = atom->line; - else surf = atom->tri; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nlocal + atom->nghost; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - // two loops over parent list required, one to count, one to store - // because onesided constraint means pair I,J may be stored with I or J - // so don't know in advance how much space to alloc for each atom's neighs - - // first loop over atoms in other list to count neighbors - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (i = 0; i < nlocal; i++) numneigh[i] = 0; - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - n = 0; - - // loop over parent non-skip granular list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - // flip I,J if necessary to satisfy onesided constraint - // do not keep if I is now ghost - - if (surf[i] >= 0) { - if (j >= nlocal) continue; - tmp = i; - i = j; - j = tmp; - flip = 1; - } else flip = 0; - - numneigh[i]++; - if (flip) i = j; - } - } - - // allocate all per-atom neigh list chunks, including history - - for (i = 0; i < nlocal; i++) { - if (numneigh[i] == 0) continue; - n = numneigh[i]; - firstneigh[i] = ipage->get(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - if (fix_history) { - firsttouch[i] = ipage_touch->get(n); - firstshear[i] = dpage_shear->get(dnum*n); - } - } - - // second loop over atoms in other list to store neighbors - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (i = 0; i < nlocal; i++) numneigh[i] = 0; - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - // loop over parent non-skip granular list and optionally its history info - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - - // flip I,J if necessary to satisfy onesided constraint - // do not keep if I is now ghost - - if (surf[i] >= 0) { - if (j >= nlocal) continue; - tmp = i; - i = j; - j = tmp; - flip = 1; - } else flip = 0; - - // store j in neigh list, not joriginal, like other neigh methods - // OK, b/c there is no special list flagging for surfs - - firstneigh[i][numneigh[i]] = j; - - // no numeric test for current touch - // just use FSH partner list to infer it - // would require complex calculation for surfs - - if (fix_history) { - jtag = tag[j]; - n = numneigh[i]; - nn = dnum*n; - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == jtag) break; - if (m < npartner[i]) { - firsttouch[i][n] = 1; - memcpy(&firstshear[i][nn],&shearpartner[i][dnum*m],dnumbytes); - } else { - firsttouch[i][n] = 0; - memcpy(&firstshear[i][nn],zeroes,dnumbytes); - } - } - - numneigh[i]++; - if (flip) i = j; - } - - // only add atom I to ilist if it has neighbors - // fix shear/history allows for this in pre_exchange_onesided() - - if (numneigh[i]) ilist[inum++] = i; - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - build skip list for subset of types from parent list - iskip and ijskip flag which atom types and type pairs to skip - this is for respa lists, copy the inner/middle values from parent -------------------------------------------------------------------------- */ - -void Neighbor::skip_from_respa(NeighList *list) -{ - int i,j,ii,jj,n,itype,jnum,joriginal,n_inner,n_middle; - int *neighptr,*jlist,*neighptr_inner,*neighptr_middle; - - int *type = atom->type; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_skip = list->listskip->ilist; - int *numneigh_skip = list->listskip->numneigh; - int **firstneigh_skip = list->listskip->firstneigh; - int inum_skip = list->listskip->inum; - - int *iskip = list->iskip; - int **ijskip = list->ijskip; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage *ipage_inner = listinner->ipage; - - int *numneigh_inner_skip = list->listskip->listinner->numneigh; - int **firstneigh_inner_skip = list->listskip->listinner->firstneigh; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int *numneigh_middle_skip,**firstneigh_middle_skip; - int respamiddle = list->respamiddle; - if (respamiddle) { - listmiddle = list->listmiddle; - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - ipage_middle = listmiddle->ipage; - numneigh_middle_skip = list->listskip->listmiddle->numneigh; - firstneigh_middle_skip = list->listskip->listmiddle->firstneigh; - } - - int inum = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - // loop over atoms in other list - // skip I atom entirely if iskip is set for type[I] - // skip I,J pair if ijskip is set for type[I],type[J] - - for (ii = 0; ii < inum_skip; ii++) { - i = ilist_skip[ii]; - itype = type[i]; - if (iskip[itype]) continue; - - n = n_inner = 0; - neighptr = ipage->vget(); - neighptr_inner = ipage_inner->vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->vget(); - } - - // loop over parent outer rRESPA list - - jlist = firstneigh_skip[i]; - jnum = numneigh_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - neighptr[n++] = joriginal; - } - - // loop over parent inner rRESPA list - - jlist = firstneigh_inner_skip[i]; - jnum = numneigh_inner_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - neighptr_inner[n_inner++] = joriginal; - } - - // loop over parent middle rRESPA list - - if (respamiddle) { - jlist = firstneigh_middle_skip[i]; - jnum = numneigh_middle_skip[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (ijskip[itype][type[j]]) continue; - neighptr_middle[n_middle++] = joriginal; - } - } - - ilist[inum] = 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[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = i; - firstneigh_middle[i] = neighptr_middle; - numneigh_middle[i] = n_middle; - ipage_middle->vgot(n); - if (ipage_middle->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - inum++; - } - - list->inum = inum; - listinner->inum = inum; - if (respamiddle) listmiddle->inum = inum; -} - -/* ---------------------------------------------------------------------- - create list which is simply a copy of parent list -------------------------------------------------------------------------- */ - -void Neighbor::copy_from(NeighList *list) -{ - NeighList *listcopy = list->listcopy; - - list->inum = listcopy->inum; - list->gnum = listcopy->gnum; - list->ilist = listcopy->ilist; - list->numneigh = listcopy->numneigh; - list->firstneigh = listcopy->firstneigh; - list->firstdouble = listcopy->firstdouble; - list->ipage = listcopy->ipage; - list->dpage = listcopy->dpage; -} diff --git a/src/neigh_full.cpp b/src/neigh_full.cpp deleted file mode 100644 index d9ff786d65..0000000000 --- a/src/neigh_full.cpp +++ /dev/null @@ -1,590 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "my_page.h" -#include "group.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - N^2 search for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void Neighbor::full_nsq(NeighList *list) -{ - int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over owned atoms, storing neighbors - - for (i = 0; i < nlocal; 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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::full_nsq_ghost(NeighList *list) -{ - int i,j,n,itype,jtype,which,imol,iatom,moltemplate; - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = 0; i < nall; 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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = atom->nlocal; - list->gnum = inum - atom->nlocal; -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void Neighbor::full_bin(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // bin owned & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over owned atoms, storing neighbors - - for (i = 0; i < nlocal; 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 = coord2bin(x[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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} - -/* ---------------------------------------------------------------------- - 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 -------------------------------------------------------------------------- */ - -void Neighbor::full_bin_ghost(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int xbin,ybin,zbin,xbin2,ybin2,zbin2; - int *neighptr; - - // bin owned & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = 0; i < nall; 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 - // 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 = coord2bin(x[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) { - 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 (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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = atom->nlocal; - list->gnum = inum - atom->nlocal; -} - -/* ---------------------------------------------------------------------- - binned neighbor list construction for all neighbors - multi-type stencil is itype dependent and is distance checked - every neighbor pair appears in list of both atoms i and j -------------------------------------------------------------------------- */ - -void Neighbor::full_multi(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 - // skip if i,j neighbor cutoff is less than bin distance - // skip i = j - - ibin = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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 (i == j) 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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; - list->gnum = 0; -} diff --git a/src/neigh_gran.cpp b/src/neigh_gran.cpp deleted file mode 100644 index be724cc08c..0000000000 --- a/src/neigh_gran.cpp +++ /dev/null @@ -1,839 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "group.h" -#include "fix_shear_history.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - granular particles - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - 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 Neighbor::granular_nsq_no_newton(NeighList *list) -{ - int i,j,m,n,nn,bitmask,dnum,dnumbytes; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr,*touchptr; - double *shearptr; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nall; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // loop over remaining atoms, owned and ghost - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - granular particles - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests -------------------------------------------------------------------------- */ - -void Neighbor::granular_nsq_newton(NeighList *list) -{ - int i,j,m,n,nn,itag,jtag,bitmask,dnum,dnumbytes; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr,*touchptr; - double *shearptr; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nall; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - itag = tag[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // loop over remaining atoms, owned and ghost - - 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 (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; - } - } - } - - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n++] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - granular particles - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - 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 Neighbor::granular_nsq_newton_onesided(NeighList *list) -{ -} - -/* ---------------------------------------------------------------------- - granular particles - binned neighbor list construction with partial Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - 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 Neighbor::granular_bin_no_newton(NeighList *list) -{ - int i,j,k,m,n,nn,ibin,dnum,dnumbytes; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr,*touchptr; - double *shearptr; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nlocal + atom->nghost; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - ibin = coord2bin(x[i]); - - // 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; - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - granular particles - binned neighbor list construction with full Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - each owned atom i checks its own bin and other bins in Newton stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::granular_bin_newton(NeighList *list) -{ - int i,j,k,m,n,nn,ibin,dnum,dnumbytes; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr,*touchptr; - double *shearptr; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nlocal + atom->nghost; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // 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; - } - } - - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - - // loop over all atoms in other bins in stencil, store every pair - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - granular particles - N^2 / 2 search for neighbor pairs with partial Newton's 3rd law - shear history must be accounted for when a neighbor pair is added - 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 Neighbor::granular_bin_newton_onesided(NeighList *list) -{ -} - -/* ---------------------------------------------------------------------- - granular particles - binned neighbor list construction with Newton's 3rd law for triclinic - shear history must be accounted for when a neighbor pair is added - each owned atom i checks its own bin and other bins in triclinic stencil - every pair stored exactly once by some processor -------------------------------------------------------------------------- */ - -void Neighbor::granular_bin_newton_tri(NeighList *list) -{ - int i,j,k,m,n,nn,ibin,dnum,dnumbytes; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - double radi,radsum,cutsq; - int *neighptr,*touchptr; - double *shearptr; - - NeighList *listgranhistory; - int *npartner; - tagint **partner; - double **shearpartner; - int **firsttouch; - double **firstshear; - MyPage *ipage_touch; - MyPage *dpage_shear; - - // bin local & ghost atoms - - bin_atoms(); - - // loop over each atom, storing neighbors - - double **x = atom->x; - double *radius = atom->radius; - tagint *tag = atom->tag; - int *type = atom->type; - int *mask = atom->mask; - tagint *molecule = atom->molecule; - int nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - FixShearHistory *fix_history = list->fix_history; - if (fix_history) { - fix_history->nlocal_neigh = nlocal; - fix_history->nall_neigh = nlocal + atom->nghost; - npartner = fix_history->npartner; - partner = fix_history->partner; - shearpartner = fix_history->shearpartner; - listgranhistory = list->listgranhistory; - firsttouch = listgranhistory->firstneigh; - firstshear = listgranhistory->firstdouble; - ipage_touch = listgranhistory->ipage; - dpage_shear = listgranhistory->dpage; - dnum = listgranhistory->dnum; - dnumbytes = dnum * sizeof(double); - } - - int inum = 0; - ipage->reset(); - if (fix_history) { - ipage_touch->reset(); - dpage_shear->reset(); - } - - for (i = 0; i < nlocal; i++) { - n = 0; - neighptr = ipage->vget(); - if (fix_history) { - nn = 0; - touchptr = ipage_touch->vget(); - shearptr = dpage_shear->vget(); - } - - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - radi = radius[i]; - - // loop over all atoms in bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && j <= i) continue; - } - } - - if (exclude && exclusion(i,j,type[i],type[j],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; - radsum = radi + radius[j]; - cutsq = (radsum+skin) * (radsum+skin); - - if (rsq <= cutsq) { - neighptr[n++] = j; - - if (fix_history) { - if (rsq < radsum*radsum) { - for (m = 0; m < npartner[i]; m++) - if (partner[i][m] == tag[j]) break; - if (m < npartner[i]) { - touchptr[n] = 1; - memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); - nn += dnum; - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } else { - touchptr[n] = 0; - memcpy(&shearptr[nn],zeroes,dnumbytes); - nn += dnum; - } - } - - n++; - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (fix_history) { - firsttouch[i] = touchptr; - firstshear[i] = shearptr; - ipage_touch->vgot(n); - dpage_shear->vgot(nn); - } - } - - list->inum = inum; -} diff --git a/src/neigh_half_bin.cpp b/src/neigh_half_bin.cpp deleted file mode 100644 index 349deddae1..0000000000 --- a/src/neigh_half_bin.cpp +++ /dev/null @@ -1,534 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "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; - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_no_newton(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 = coord2bin(x[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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_no_newton_ghost(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int xbin,ybin,zbin,xbin2,ybin2,zbin2; - int *neighptr; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nall; 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 = coord2bin(x[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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = atom->nlocal; - list->gnum = inum - atom->nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_newton(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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) { - 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 = coord2bin(x[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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_bin_newton_tri(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && 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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/neigh_half_multi.cpp b/src/neigh_half_multi.cpp deleted file mode 100644 index 9d8375b68e..0000000000 --- a/src/neigh_half_multi.cpp +++ /dev/null @@ -1,415 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "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; - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_multi_no_newton(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_multi_newton(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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) { - 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 = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_multi_newton_tri(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*s; - double *cutsq,*distsq; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 bins, including self, in stencil - // skip if i,j neighbor cutoff is less than bin distance - // bins below self are excluded from stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - cutsq = cutneighsq[itype]; - ns = nstencil_multi[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 (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && j <= i) 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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/neigh_half_multi.h b/src/neigh_half_multi.h deleted file mode 100644 index 1538f7662a..0000000000 --- a/src/neigh_half_multi.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ERROR/WARNING messages: - -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - -*/ diff --git a/src/neigh_half_nsq.cpp b/src/neigh_half_nsq.cpp deleted file mode 100644 index 17ce63c775..0000000000 --- a/src/neigh_half_nsq.cpp +++ /dev/null @@ -1,360 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "group.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_nsq_no_newton(NeighList *list) -{ - int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over owned atoms, storing neighbors - - for (i = 0; i < nlocal; 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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_nsq_no_newton_ghost(NeighList *list) -{ - int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = 0; i < nall; 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) { - 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[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = atom->nlocal; - list->gnum = inum - atom->nlocal; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::half_nsq_newton(NeighList *list) -{ - int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int inum = 0; - ipage->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 - // itag = jtag is possible for long cutoffs that include images of self - - 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 (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; - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - } - - list->inum = inum; -} diff --git a/src/neigh_half_nsq.h b/src/neigh_half_nsq.h deleted file mode 100644 index 1538f7662a..0000000000 --- a/src/neigh_half_nsq.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ERROR/WARNING messages: - -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - -*/ diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 299a8704ba..f8d496fc6b 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -25,14 +25,15 @@ using namespace LAMMPS_NS; #define PGDELTA 1 -enum{NSQ,BIN,MULTI}; // also in neighbor.cpp +enum{NSQ,BIN,MULTI}; // also in Neighbor /* ---------------------------------------------------------------------- */ -NeighList::NeighList(LAMMPS *lmp) : - Pointers(lmp) +NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) { - maxatoms = 0; + // initializations + + maxatom = 0; inum = gnum = 0; ilist = NULL; @@ -40,9 +41,15 @@ NeighList::NeighList(LAMMPS *lmp) : firstneigh = NULL; firstdouble = NULL; + // defaults, but may be reset by post_constructor() + + occasional = 0; + ghost = 0; + ssa = 0; + copy = 0; dnum = 0; - last_build = -1; + // ptrs iskip = NULL; ijskip = NULL; @@ -57,74 +64,114 @@ NeighList::NeighList(LAMMPS *lmp) : listcopy = NULL; listskip = NULL; - // USER-DPD package - - ssaflag = 0; - ndxAIR_ssa = NULL; - maxbin_ssa = 0; - bins_ssa = NULL; - maxhead_ssa = 0; - binhead_ssa = NULL; - gbinhead_ssa = NULL; - - maxstencil = ghostflag = 0; - stencil = NULL; - stencilxyz = NULL; - - maxstencil_multi = 0; - nstencil_multi = NULL; - stencil_multi = NULL; - distsq_multi = NULL; - ipage = NULL; dpage = NULL; + + // Kokkos package + + kokkos = 0; + execution_space = Host; + + // USER-DPD package + + ndxAIR_ssa = NULL; } /* ---------------------------------------------------------------------- */ NeighList::~NeighList() { - if (!listcopy) { + if (!copy) { memory->destroy(ilist); memory->destroy(numneigh); memory->sfree(firstneigh); memory->sfree(firstdouble); delete [] ipage; - if (dnum) delete [] dpage; + delete [] dpage; } delete [] iskip; memory->destroy(ijskip); - if (maxstencil) memory->destroy(stencil); - if (ghostflag) memory->destroy(stencilxyz); - if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa); - if (maxbin_ssa) memory->destroy(bins_ssa); - if (maxhead_ssa) { - memory->destroy(binhead_ssa); - memory->destroy(gbinhead_ssa); + if (ssa) { + memory->sfree(ndxAIR_ssa); + } +} + +/* ---------------------------------------------------------------------- + adjust settings to match corresponding NeighRequest + cannot do this in constructor b/c not all NeighLists are allocated yet + copy -> set listcopy for list to copy from + skip -> set listskip and create local copy of itype,ijtype + halffull -> preceeding list must be full + granhistory -> preceeding list must be gran, set its LGH and FH ptrs + respaouter -> preceeding list(s) must be inner or middle, set LM/LI ptrs +------------------------------------------------------------------------- */ + +void NeighList::post_constructor(NeighRequest *nq) +{ + occasional = nq->occasional; + ghost = nq->ghost; + ssa = nq->ssa; + copy = nq->copy; + dnum = nq->dnum; + + if (nq->copy) + listcopy = neighbor->lists[nq->otherlist]; + + if (nq->skip) { + listskip = neighbor->lists[nq->otherlist]; + int ntypes = atom->ntypes; + iskip = new int[ntypes+1]; + memory->create(ijskip,ntypes+1,ntypes+1,"neigh_list:ijskip"); + int i,j; + for (i = 1; i <= ntypes; i++) iskip[i] = nq->iskip[i]; + for (i = 1; i <= ntypes; i++) + for (j = 1; j <= ntypes; j++) + ijskip[i][j] = nq->ijskip[i][j]; } - if (maxstencil_multi) { - for (int i = 1; i <= atom->ntypes; i++) { - memory->destroy(stencil_multi[i]); - memory->destroy(distsq_multi[i]); - } - delete [] nstencil_multi; - delete [] stencil_multi; - delete [] distsq_multi; + if (nq->half_from_full) { + NeighRequest *oq = neighbor->requests[nq->index-1]; + if (oq->full != 1) + error->all(FLERR,"Neighbor half-from-full list does not follow " + "full list"); + listfull = neighbor->lists[nq->index-1]; + } + + if (nq->granhistory) { + NeighRequest *oq = neighbor->requests[nq->index-1]; + if (oq->gran != 1) + error->all(FLERR,"Neighbor granhistory list does not follow gran list"); + neighbor->lists[nq->index-1]->listgranhistory = this; + neighbor->lists[nq->index-1]->fix_history = nq->fix_history; + } + + if (nq->respaouter) { + NeighRequest *oq = neighbor->requests[nq->index-1]; + if (oq->respainner) { + respamiddle = 0; + listinner = neighbor->lists[nq->index-1]; + } else if (oq->respamiddle) { + respamiddle = 1; + listmiddle = neighbor->lists[nq->index-1]; + oq = neighbor->requests[nq->index-2]; + if (!oq->respainner) + error->all(FLERR,"Neighbor respa outer list does not follow " + "respa list"); + listinner = neighbor->lists[nq->index-2]; + } else + error->all(FLERR,"Neighbor respa outer list does not follow respa list"); } } /* ---------------------------------------------------------------------- */ -void NeighList::setup_pages(int pgsize_caller, int oneatom_caller, - int dnum_caller) +void NeighList::setup_pages(int pgsize_caller, int oneatom_caller) { pgsize = pgsize_caller; oneatom = oneatom_caller; - dnum = dnum_caller; int nmypage = comm->nthreads; ipage = new MyPage[nmypage]; @@ -135,104 +182,56 @@ void NeighList::setup_pages(int pgsize_caller, int oneatom_caller, dpage = new MyPage[nmypage]; for (int i = 0; i < nmypage; i++) dpage[i].init(dnum*oneatom,dnum*pgsize,PGDELTA); - } - else dpage = NULL; + } else dpage = NULL; } /* ---------------------------------------------------------------------- - grow atom arrays to allow for nmax atoms - triggered by more atoms on a processor - caller knows if this list stores neighs of local atoms or local+ghost + grow per-atom data to allow for nlocal/nall atoms + for parent lists: + also trigger grow in child list(s) which are not built themselves + gran calls grow() in granhistory + respaouter calls grow() in respainner, respamiddle + triggered by neighbor list build ------------------------------------------------------------------------- */ -void NeighList::grow(int nmax) +void NeighList::grow(int nlocal, int nall) { - // skip if this list is already long enough to store nmax atoms + // trigger grow() in children before possible return - if (nmax <= maxatoms) return; - maxatoms = nmax; + if (listgranhistory) listgranhistory->grow(nlocal,nall); + if (listinner) listinner->grow(nlocal,nall); + if (listmiddle) listmiddle->grow(nlocal,nall); + + // skip if data structs are already big enough + + if (ghost) { + if (nall <= maxatom) return; + } else { + if (nlocal <= maxatom) return; + } + + maxatom = atom->nmax; memory->destroy(ilist); memory->destroy(numneigh); memory->sfree(firstneigh); - memory->sfree(firstdouble); - - memory->create(ilist,maxatoms,"neighlist:ilist"); - memory->create(numneigh,maxatoms,"neighlist:numneigh"); - firstneigh = (int **) memory->smalloc(maxatoms*sizeof(int *), + memory->create(ilist,maxatom,"neighlist:ilist"); + memory->create(numneigh,maxatom,"neighlist:numneigh"); + firstneigh = (int **) memory->smalloc(maxatom*sizeof(int *), "neighlist:firstneigh"); - if (dnum) - firstdouble = (double **) memory->smalloc(maxatoms*sizeof(double *), + if (dnum) { + memory->sfree(firstdouble); + firstdouble = (double **) memory->smalloc(maxatom*sizeof(double *), "neighlist:firstdouble"); - if (ssaflag) { + } + + if (ssa) { if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa); - ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatoms, + ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatom, "neighlist:ndxAIR_ssa"); } } -/* ---------------------------------------------------------------------- - insure stencils are large enough for smax bins - style = BIN or MULTI -------------------------------------------------------------------------- */ - -void NeighList::stencil_allocate(int smax, int style) -{ - int i; - - if (style == BIN) { - if (smax > maxstencil) { - maxstencil = smax; - memory->destroy(stencil); - memory->create(stencil,maxstencil,"neighlist:stencil"); - if (ghostflag) { - memory->destroy(stencilxyz); - memory->create(stencilxyz,maxstencil,3,"neighlist:stencilxyz"); - } - } - - } else { - int n = atom->ntypes; - if (maxstencil_multi == 0) { - nstencil_multi = new int[n+1]; - stencil_multi = new int*[n+1]; - distsq_multi = new double*[n+1]; - for (i = 1; i <= n; i++) { - nstencil_multi[i] = 0; - stencil_multi[i] = NULL; - distsq_multi[i] = NULL; - } - } - if (smax > maxstencil_multi) { - maxstencil_multi = smax; - for (i = 1; i <= n; i++) { - memory->destroy(stencil_multi[i]); - memory->destroy(distsq_multi[i]); - memory->create(stencil_multi[i],maxstencil_multi, - "neighlist:stencil_multi"); - memory->create(distsq_multi[i],maxstencil_multi, - "neighlist:distsq_multi"); - } - } - } -} - -/* ---------------------------------------------------------------------- - copy skip info from request rq into list's iskip,ijskip -------------------------------------------------------------------------- */ - -void NeighList::copy_skip_info(int *rq_iskip, int **rq_ijskip) -{ - int ntypes = atom->ntypes; - iskip = new int[ntypes+1]; - memory->create(ijskip,ntypes+1,ntypes+1,"neigh_list:ijskip"); - int i,j; - for (i = 1; i <= ntypes; i++) iskip[i] = rq_iskip[i]; - for (i = 1; i <= ntypes; i++) - for (j = 1; j <= ntypes; j++) - ijskip[i][j] = rq_ijskip[i][j]; -} - /* ---------------------------------------------------------------------- print attributes of this list and associated request ------------------------------------------------------------------------- */ @@ -246,11 +245,11 @@ void NeighList::print_attributes() printf("Neighbor list/request %d:\n",index); printf(" %p = requestor ptr (instance %d id %d)\n", rq->requestor,rq->requestor_instance,rq->id); - printf(" %d = build flag\n",buildflag); - printf(" %d = grow flag\n",growflag); - printf(" %d = stencil flag\n",stencilflag); - printf(" %d = ghost flag\n",ghostflag); - printf(" %d = ssa flag\n",ssaflag); + printf(" %d = occasional\n",occasional); + printf(" %d = ghost flag\n",ghost); + printf(" %d = ssa flag\n",ssa); + printf(" %d = copy flag\n",copy); + printf(" %d = dnum\n",dnum); printf("\n"); printf(" %d = pair\n",rq->pair); printf(" %d = fix\n",rq->fix); @@ -266,17 +265,12 @@ void NeighList::print_attributes() printf(" %d = respaouter\n",rq->respaouter); printf(" %d = half_from_full\n",rq->half_from_full); printf("\n"); - printf(" %d = occasional\n",rq->occasional); printf(" %d = newton\n",rq->newton); printf(" %d = granonesided\n",rq->granonesided); - printf(" %d = dnum\n",rq->dnum); - printf(" %d = ghost\n",rq->ghost); printf(" %d = omp\n",rq->omp); printf(" %d = intel\n",rq->intel); printf(" %d = kokkos host\n",rq->kokkos_host); printf(" %d = kokkos device\n",rq->kokkos_device); - printf(" %d = ssa\n",rq->ssa); - printf(" %d = copy\n",rq->copy); printf(" %d = skip\n",rq->skip); printf(" %d = otherlist\n",rq->otherlist); printf(" %p = listskip\n",(void *)listskip); @@ -285,16 +279,16 @@ void NeighList::print_attributes() /* ---------------------------------------------------------------------- return # of bytes of allocated memory - if growflag = 0, maxatoms & maxpage will also be 0 + if growflag = 0, maxatom & maxpage will also be 0 if stencilflag = 0, maxstencil * maxstencil_multi will also be 0 ------------------------------------------------------------------------- */ bigint NeighList::memory_usage() { bigint bytes = 0; - bytes += memory->usage(ilist,maxatoms); - bytes += memory->usage(numneigh,maxatoms); - bytes += maxatoms * sizeof(int *); + bytes += memory->usage(ilist,maxatom); + bytes += memory->usage(numneigh,maxatom); + bytes += maxatom * sizeof(int *); int nmypage = comm->nthreads; @@ -305,24 +299,12 @@ bigint NeighList::memory_usage() if (dnum && dpage) { for (int i = 0; i < nmypage; i++) { - bytes += maxatoms * sizeof(double *); + bytes += maxatom * sizeof(double *); bytes += dpage[i].size(); } } - if (maxstencil) bytes += memory->usage(stencil,maxstencil); - if (ghostflag) bytes += memory->usage(stencilxyz,maxstencil,3); - if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatoms; - if (maxbin_ssa) bytes += memory->usage(bins_ssa,maxbin_ssa); - if (maxhead_ssa) { - bytes += memory->usage(binhead_ssa,maxhead_ssa); - bytes += memory->usage(gbinhead_ssa,maxhead_ssa); - } - - if (maxstencil_multi) { - bytes += memory->usage(stencil_multi,atom->ntypes,maxstencil_multi); - bytes += memory->usage(distsq_multi,atom->ntypes,maxstencil_multi); - } + if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatom; return bytes; } diff --git a/src/neigh_list.h b/src/neigh_list.h index d76682dfc4..3b6a4d6760 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -21,14 +21,21 @@ namespace LAMMPS_NS { class NeighList : protected Pointers { public: - int index; // index of which neigh list it is - // needed when a class invokes it directly - // also indexes the request it came from + int index; // index of which neigh list this is + // also indexes the request it came from + // and the npair list of NPair classes - int buildflag; // 1 if pair_build invoked every reneigh - int growflag; // 1 if stores atom-based arrays & pages - int stencilflag; // 1 if stores stencil arrays - int ghostflag; // 1 if it stores neighbors of ghosts + int bin_method; // 0 if no binning, else 1-N index into binnames + int stencil_method; // 0 if no stencil, else 1-N index into stencilnames + int pair_method; // 0 if no pair, else 1-N index into pairnames + + // settings from NeighRequest + + int occasional; // 0 if build every reneighbor, 1 if not + int ghost; // 1 if list stores neighbors of ghosts + int ssa; // 1 if list stores Shardlow data + int copy; // 1 if this list copied from another list + int dnum; // # of doubles per neighbor, 0 if none // data structs to store neighbor pairs I,J and associated values @@ -41,14 +48,11 @@ class NeighList : protected Pointers { int pgsize; // size of each page int oneatom; // max size for one atom - int dnum; // # of doubles per neighbor, 0 if none MyPage *ipage; // pages of neighbor indices MyPage *dpage; // pages of neighbor doubles, if dnum > 0 - bigint last_build; // timestep of last build for occasional lists - // atom types to skip when building list - // iskip,ijskip are just ptrs to corresponding request + // copied info from corresponding request into realloced vec/array int *iskip; // iskip[i] = 1 if atoms of type I are not in list int **ijskip; // ijskip[i][j] = 1 if pairs of type I,J are not in list @@ -65,40 +69,28 @@ class NeighList : protected Pointers { NeighList *listcopy; // me = copy list, point to list I copy from NeighList *listskip; // me = skip list, point to list I skip from + // Kokkos package + + int kokkos; // 1 if list stores Kokkos data + ExecutionSpace execution_space; + // USER-DPD package and Shardlow Splitting Algorithm (SSA) support - int ssaflag; // 1 if the list has the ndxAIR_ssa array uint16_t (*ndxAIR_ssa)[8]; // for each atom, last neighbor index of each AIR - int *bins_ssa; // index of next atom in each bin - int maxbin_ssa; // size of bins_ssa array - int *binhead_ssa; // index of 1st local atom in each bin - int *gbinhead_ssa; // index of 1st ghost atom in each bin - int maxhead_ssa; // size of binhead_ssa and gbinhead_ssa arrays - // stencils of bin indices for neighbor finding - - int maxstencil; // max size of stencil - int nstencil; // # of bins in stencil - int *stencil; // list of bin offsets - int **stencilxyz; // bin offsets in xyz dims - - int maxstencil_multi; // max sizes of stencils - int *nstencil_multi; // # bins in each type-based multi stencil - int **stencil_multi; // list of bin offsets in each stencil - double **distsq_multi; // sq distances to bins in each stencil + // methods NeighList(class LAMMPS *); virtual ~NeighList(); - void setup_pages(int, int, int); // setup page data structures - void grow(int); // grow maxlocal - void stencil_allocate(int, int); // allocate stencil arrays - void copy_skip_info(int *, int **); // copy skip info from a neigh request + void post_constructor(class NeighRequest *); + void setup_pages(int, int); // setup page data structures + void grow(int,int); // grow all data structs void print_attributes(); // debug routine - int get_maxlocal() {return maxatoms;} + int get_maxlocal() {return maxatom;} bigint memory_usage(); protected: - int maxatoms; // size of allocated atom arrays + int maxatom; // size of allocated per-atom arrays }; } diff --git a/src/neigh_request.cpp b/src/neigh_request.cpp index cc8c0d7c99..4a3eb14933 100644 --- a/src/neigh_request.cpp +++ b/src/neigh_request.cpp @@ -24,7 +24,6 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) // default ID = 0 id = 0; - unprocessed = 1; // class user of list: default is pair request // only one is set to 1 @@ -37,16 +36,19 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) half = 1; full = 0; - full_cluster = 0; - gran = 0; + gran = granhistory = 0; respainner = respamiddle = respaouter = 0; half_from_full = 0; + full_cluster = 0; + + // only set when command = 1; + + command_style = NULL; // combination of settings, mutiple can be set to 1 // default is every reneighboring // default is use newton_pair setting in force - // default is encode special bond flags - // default is no granular history (when gran = 1) + // default is no size history (when gran = 1) // default is no one-sided sphere/surface interactions (when gran = 1) // default is no auxiliary floating point values // default is no neighbors of ghosts @@ -56,8 +58,6 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) occasional = 0; newton = 0; - //special = 1; - granhistory = 0; granonesided = 0; dnum = 0; ghost = 0; @@ -73,6 +73,7 @@ NeighRequest::NeighRequest(LAMMPS *lmp) : Pointers(lmp) skip = 0; iskip = NULL; ijskip = NULL; + off2on = 0; otherlist = -1; } @@ -113,8 +114,6 @@ int NeighRequest::identical(NeighRequest *other) // and appearing to be old, when it is really new // only needed for classes with persistent neigh lists: Fix, Compute, Pair - if (other->unprocessed) same = 0; - if (requestor != other->requestor) same = 0; if (requestor_instance != other->requestor_instance) same = 0; if (id != other->id) same = 0; @@ -134,7 +133,6 @@ int NeighRequest::identical(NeighRequest *other) if (newton != other->newton) same = 0; if (occasional != other->occasional) same = 0; - //if (special != other->special) same = 0; if (granhistory != other->granhistory) same = 0; if (granonesided != other->granonesided) same = 0; if (dnum != other->dnum) same = 0; diff --git a/src/neigh_request.h b/src/neigh_request.h index 16d4dfddaf..0b561710e7 100644 --- a/src/neigh_request.h +++ b/src/neigh_request.h @@ -20,12 +20,11 @@ namespace LAMMPS_NS { class NeighRequest : protected Pointers { public: + int index; // index of which neigh request this is void *requestor; // class that made request int requestor_instance; // instance of that class (only Fix, Compute, Pair) int id; // ID of request as stored by requestor // used to track multiple requests from one class - int unprocessed; // 1 when first requested - // 0 after processed by Neighbor class // which class style requests the list, one flag is 1, others are 0 @@ -35,16 +34,20 @@ class NeighRequest : protected Pointers { int command; // kind of list requested, one flag is 1, others are 0 + // NOTE: should make only the first 3 settings be unique, + // allow others as add-on flags + // this will require changed flags in pair requestors + // this will lead to simpler logic in Neighbor::choose_build() int half; // 1 if half neigh list (set by default) int full; // 1 if full neigh list - int full_cluster; // only used by Kokkos pair styles + int half_from_full; // 1 if half list computed from previous full list int gran; // 1 if granular list int granhistory; // 1 if history info for granular contact pairs int respainner; // 1 if a rRESPA inner list int respamiddle; // 1 if a rRESPA middle list int respaouter; // 1 if a rRESPA outer list - int half_from_full; // 1 if half list computed from previous full list + int full_cluster; // only used by Kokkos pair styles // command_style only set if command = 1 // allows print_pair_info() to access command name @@ -52,7 +55,7 @@ class NeighRequest : protected Pointers { const char *command_style; // ----------------- - // optional settings + // optional settings, set by caller, all are 0 by default // ----------------- // 0 if needed every reneighboring during run @@ -66,11 +69,6 @@ class NeighRequest : protected Pointers { int newton; - // 0 if user of list wants no encoding of special bond flags and all neighs - // 1 if user of list wants special bond flags encoded, set by default - - //int special; - // 1 if one-sided granular list for sphere/surf interactions (gran = 1) int granonesided; @@ -96,9 +94,13 @@ class NeighRequest : protected Pointers { // 1 if using Shardlow Splitting Algorithm (SSA) neighbor list build int ssa; + + // ----------------- + // end of optional settings + // ----------------- - // set by neighbor and pair_hybrid after all requests are made - // these settings do not change kind value + // set by pair_hybrid and neighbor after all requests are made + // these settings do not change kind value or optional settings int copy; // 1 if this list copied from another list diff --git a/src/neigh_respa.cpp b/src/neigh_respa.cpp deleted file mode 100644 index 777534746b..0000000000 --- a/src/neigh_respa.cpp +++ /dev/null @@ -1,928 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "group.h" -#include "my_page.h" -#include "error.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - 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 Neighbor::respa_nsq_no_newton(NeighList *list) -{ - int i,j,n,itype,jtype,n_inner,n_middle,bitmask,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - listmiddle = list->listmiddle; - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - ipage_middle = listmiddle->ipage; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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) { - 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[inum] = 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[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = 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"); - } - - inum++; - } - - list->inum = inum; - listinner->inum = inum; - if (respamiddle) listmiddle->inum = inum; -} - -/* ---------------------------------------------------------------------- - multiple respa lists - N^2 / 2 search for neighbor pairs with full Newton's 3rd law - pair added to list if atoms i and j are both owned and i < j - if j is ghost only me or other proc adds pair - decision based on itag,jtag tests -------------------------------------------------------------------------- */ - -void Neighbor::respa_nsq_newton(NeighList *list) -{ - int i,j,n,itype,jtype,itag,jtag,n_inner,n_middle,bitmask; - int imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - if (includegroup) { - nlocal = atom->nfirst; - bitmask = group->bitmask[includegroup]; - } - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - listmiddle = list->listmiddle; - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - ipage_middle = listmiddle->ipage; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; i++) { - n = n_inner = 0; - neighptr = ipage->vget(); - neighptr_inner = ipage_inner->vget(); - if (respamiddle) { - n_middle = 0; - neighptr_middle = ipage_middle->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 - - 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 (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 ((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[inum] = 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[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = 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"); - } - - inum++; - } - - list->inum = inum; - listinner->inum = inum; - if (respamiddle) listmiddle->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::respa_bin_no_newton(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - listmiddle = list->listmiddle; - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - ipage_middle = listmiddle->ipage; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 = coord2bin(x[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) { - 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[inum] = 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[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = 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"); - } - - inum++; - } - - list->inum = inum; - listinner->inum = inum; - if (respamiddle) listmiddle->inum = inum; -} - -/* ---------------------------------------------------------------------- - 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 Neighbor::respa_bin_newton(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - listmiddle = list->listmiddle; - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - ipage_middle = listmiddle->ipage; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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) { - 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 = coord2bin(x[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) { - 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[inum] = 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[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = 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"); - } - - inum++; - } - - list->inum = inum; - listinner->inum = inum; - if (respamiddle) listmiddle->inum = inum; -} - -/* ---------------------------------------------------------------------- - multiple respa lists - 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 Neighbor::respa_bin_newton_tri(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; - tagint tagprev; - double xtmp,ytmp,ztmp,delx,dely,delz,rsq; - int *neighptr,*neighptr_inner,*neighptr_middle; - - // bin local & ghost atoms - - if (binatomflag) bin_atoms(); - - 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 nlocal = atom->nlocal; - if (includegroup) nlocal = atom->nfirst; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage *ipage_middle; - int respamiddle = list->respamiddle; - if (respamiddle) { - listmiddle = list->listmiddle; - ilist_middle = listmiddle->ilist; - numneigh_middle = listmiddle->numneigh; - firstneigh_middle = listmiddle->firstneigh; - ipage_middle = listmiddle->ipage; - } - - int inum = 0; - int which = 0; - int minchange = 0; - ipage->reset(); - ipage_inner->reset(); - if (respamiddle) ipage_middle->reset(); - - // loop over each atom, storing neighbors - - for (i = 0; i < nlocal; 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 all atoms in bins in stencil - // pairs for atoms j "below" i are excluded - // below = lower z or (equal z and lower y) or (equal zy and lower x) - // (equal zyx and j <= i) - // latter excludes self-self interaction but allows superposed atoms - - ibin = coord2bin(x[i]); - for (k = 0; k < nstencil; k++) { - for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp) { - if (x[j][0] < xtmp) continue; - if (x[j][0] == xtmp && 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) { - 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[inum] = 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[inum] = i; - firstneigh_inner[i] = neighptr_inner; - numneigh_inner[i] = n_inner; - ipage_inner->vgot(n_inner); - if (ipage_inner->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - if (respamiddle) { - ilist_middle[inum] = 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"); - } - - inum++; - } - - list->inum = inum; - listinner->inum = inum; - if (respamiddle) listmiddle->inum = inum; -} diff --git a/src/neigh_respa.h b/src/neigh_respa.h deleted file mode 100644 index 1538f7662a..0000000000 --- a/src/neigh_respa.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ERROR/WARNING messages: - -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - -*/ diff --git a/src/neigh_shardlow.cpp b/src/neigh_shardlow.cpp deleted file mode 100644 index 1b87ab65d7..0000000000 --- a/src/neigh_shardlow.cpp +++ /dev/null @@ -1,438 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- - Contributing authors: - James Larentzos and Timothy I. Mattox (Engility Corporation) -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neigh_list.h" -#include "neigh_request.h" -#include "atom.h" -#include "atom_vec.h" -#include "molecule.h" -#include "domain.h" -#include "group.h" -#include "memory.h" -#include "error.h" -#include "update.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - routines to create a stencil = list of bin offsets - stencil = bins whose closest corner to central bin is within cutoff - sx,sy,sz = bin bounds = furthest the stencil could possibly extend - 3d creates xyz stencil, 2d creates xy stencil - for half list with newton on: - stencil is bins to the "upper right" of central bin - stencil does not include self -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_2d_ssa(NeighList *list, - int sx, int sy, int sz) -{ - int i,j; - int *stencil = list->stencil; - int nstencil = 0; - - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; - - list->nstencil = nstencil; - - // Now include additional bins for AIR ghosts only - for (j = -sy; j <= 0; j++) - for (i = -sx; i <= sx; i++) { - if (j == 0 && i > 0) continue; - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; - } - - while (nstencil < list->maxstencil) { - stencil[nstencil++] = INT_MAX; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_3d_ssa(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k; - int *stencil = list->stencil; - int nstencil = 0; - - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,k) < cutneighmaxsq) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - - list->nstencil = nstencil; - - // Now include additional bins for AIR ghosts only - for (k = -sz; k < 0; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,k) < cutneighmaxsq) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - k = 0; // skip already included bins at k == 0 - for (j = -sy; j <= 0; j++) - for (i = -sx; i <= sx; i++) { - if (j == 0 && i > 0) continue; - if (bin_distance(i,j,k) < cutneighmaxsq) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - } - - while (nstencil < list->maxstencil) { - stencil[nstencil++] = INT_MAX; - } -} - -// space for static variable ssaAIRptr so it -// can be used in qsort's compair function "cmp_ssaAIR()" -static int *ssaAIRptr; - -static int cmp_ssaAIR(const void *iptr, const void *jptr) -{ - int i = *((int *) iptr); - int j = *((int *) jptr); - if (ssaAIRptr[i] < ssaAIRptr[j]) return -1; - if (ssaAIRptr[i] > ssaAIRptr[j]) return 1; - return 0; -} - - -/* ---------------------------------------------------------------------- - build half list from full list for use by Shardlow Spliting Algorithm - 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 -------------------------------------------------------------------------- */ - -void Neighbor::half_from_full_newton_ssa(NeighList *list) -{ - int i,j,ii,jj,n,jnum,joriginal; - int *neighptr,*jlist; - - int nlocal = atom->nlocal; - int *ssaAIR = atom->ssaAIR; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - MyPage *ipage = list->ipage; - - int *ilist_full = list->listfull->ilist; - int *numneigh_full = list->listfull->numneigh; - int **firstneigh_full = list->listfull->firstneigh; - int inum_full = list->listfull->inum; - - int inum = 0; - ipage->reset(); - - // loop over parent full list - - for (ii = 0; ii < inum_full; ii++) { - int AIRct[8] = { 0 }; - n = 0; - neighptr = ipage->vget(); - - i = ilist_full[ii]; - - // loop over full neighbor list - - jlist = firstneigh_full[i]; - jnum = numneigh_full[i]; - - for (jj = 0; jj < jnum; jj++) { - joriginal = jlist[jj]; - j = joriginal & NEIGHMASK; - if (j < nlocal) { - if (i > j) continue; - ++(AIRct[0]); - } else { - if (ssaAIR[j] < 2) continue; // skip ghost atoms not in AIR - ++(AIRct[ssaAIR[j] - 1]); - } - neighptr[n++] = joriginal; - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - // sort the locals+ghosts in the neighbor list by their ssaAIR number - ssaAIRptr = atom->ssaAIR; - qsort(&(neighptr[0]), n, sizeof(int), cmp_ssaAIR); - - // Do a prefix sum on the counts to turn them into indexes. - list->ndxAIR_ssa[i][0] = AIRct[0]; - for (int ndx = 1; ndx < 8; ++ndx) { - list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; - } - } - - list->inum = inum; -} - -/* ---------------------------------------------------------------------- - for Shardlow Spliting Algorithm: - 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 Neighbor::half_bin_newton_ssa(NeighList *list) -{ - int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; - 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 nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - int *ssaAIR = atom->ssaAIR; - - int *molindex = atom->molindex; - int *molatom = atom->molatom; - Molecule **onemols = atom->avec->onemols; - int molecular = atom->molecular; - if (molecular == 2) moltemplate = 1; - else moltemplate = 0; - - int *ilist = list->ilist; - int *numneigh = list->numneigh; - int **firstneigh = list->firstneigh; - int nstencil = list->nstencil; - int maxstencil = list->maxstencil; - int *stencil = list->stencil; - MyPage *ipage = list->ipage; - - int inum = 0; - - if (binatomflag) { /* only false in Neighbor::build_one */ -/* ---------------------------------------------------------------------- - bin owned and ghost atoms for use by Shardlow Splitting Algorithm - exclude ghost atoms that are not in the Active Interaction Regions (AIR) -------------------------------------------------------------------------- */ - - if (mbins > list->maxhead_ssa) { - list->maxhead_ssa = mbins; - memory->destroy(list->gbinhead_ssa); - memory->destroy(list->binhead_ssa); - memory->create(list->binhead_ssa,list->maxhead_ssa,"binhead_ssa"); - memory->create(list->gbinhead_ssa,list->maxhead_ssa,"gbinhead_ssa"); - } - for (i = 0; i < mbins; i++) { - list->gbinhead_ssa[i] = -1; - list->binhead_ssa[i] = -1; - } - - if (maxbin > list->maxbin_ssa) { - list->maxbin_ssa = maxbin; - memory->destroy(list->bins_ssa); - memory->create(list->bins_ssa,list->maxbin_ssa,"bins_ssa"); - } - - // bin in reverse order so linked list will be in forward order - - if (includegroup) { - int bitmask = group->bitmask[includegroup]; - for (i = nall-1; i >= nlocal; i--) { - if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR - if (mask[i] & bitmask) { - ibin = coord2bin(x[i]); - list->bins_ssa[i] = list->gbinhead_ssa[ibin]; - list->gbinhead_ssa[ibin] = i; - } - } - nlocal = atom->nfirst; // This is important for the code that follows! - } else { - for (i = nall-1; i >= nlocal; i--) { - if (ssaAIR[i] < 2) continue; // skip ghost atoms not in AIR - ibin = coord2bin(x[i]); - list->bins_ssa[i] = list->gbinhead_ssa[ibin]; - list->gbinhead_ssa[ibin] = i; - } - } - for (i = nlocal-1; i >= 0; i--) { - ibin = coord2bin(x[i]); - list->bins_ssa[i] = list->binhead_ssa[ibin]; - list->binhead_ssa[ibin] = i; - } - } /* else reuse previous binning. See Neighbor::build_one comment. */ - - ipage->reset(); - - // loop over owned atoms, storing half of the neighbors - - for (i = 0; i < nlocal; i++) { - int AIRct[8] = { 0 }; - 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 local atoms in i's bin - // just store them, since j is beyond i in linked list - - for (j = list->bins_ssa[i]; j >= 0; j = list->bins_ssa[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) { - 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; - } - } - - ibin = coord2bin(x[i]); - - // loop over all local atoms in other bins in "half" stencil - for (k = 0; k < nstencil; k++) { - for (j = list->binhead_ssa[ibin+stencil[k]]; j >= 0; j = list->bins_ssa[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) { - 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; - } - } - } - AIRct[0] = n; - - // loop over AIR ghost atoms in all bins in "full" stencil - // Note: the non-AIR ghost atoms have already been filtered out - // That is a significant time savings because of the "full" stencil - // Note2: only non-pure locals can have ghosts as neighbors - if (ssaAIR[i] == 1) for (k = 0; k < maxstencil; k++) { - if (stencil[k] > mbins) break; /* Check if ghost stencil bins are exhausted */ - for (j = list->gbinhead_ssa[ibin+stencil[k]]; j >= 0; j = list->bins_ssa[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) { - 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; - ++(AIRct[ssaAIR[j] - 1]); - } else if (domain->minimum_image_check(delx,dely,delz)) { - neighptr[n++] = j; - ++(AIRct[ssaAIR[j] - 1]); - } else if (which > 0) { - neighptr[n++] = j ^ (which << SBBITS); - ++(AIRct[ssaAIR[j] - 1]); - } - } else { - neighptr[n++] = j; - ++(AIRct[ssaAIR[j] - 1]); - } - } - } - } - - ilist[inum++] = i; - firstneigh[i] = neighptr; - numneigh[i] = n; - ipage->vgot(n); - if (ipage->status()) - error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); - - // sort the ghosts in the neighbor list by their ssaAIR number - ssaAIRptr = atom->ssaAIR; - qsort(&(neighptr[AIRct[0]]), n - AIRct[0], sizeof(int), cmp_ssaAIR); - - // Do a prefix sum on the counts to turn them into indexes. - list->ndxAIR_ssa[i][0] = AIRct[0]; - for (int ndx = 1; ndx < 8; ++ndx) { - list->ndxAIR_ssa[i][ndx] = AIRct[ndx] + list->ndxAIR_ssa[i][ndx - 1]; - } - } - - list->inum = inum; -} diff --git a/src/neigh_shardlow.h b/src/neigh_shardlow.h deleted file mode 100644 index 1538f7662a..0000000000 --- a/src/neigh_shardlow.h +++ /dev/null @@ -1,22 +0,0 @@ -/* -*- c++ -*- ---------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -/* ERROR/WARNING messages: - -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - -*/ diff --git a/src/neigh_stencil.cpp b/src/neigh_stencil.cpp deleted file mode 100644 index 65fd860d2b..0000000000 --- a/src/neigh_stencil.cpp +++ /dev/null @@ -1,536 +0,0 @@ -/* ---------------------------------------------------------------------- - LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator - http://lammps.sandia.gov, Sandia National Laboratories - Steve Plimpton, sjplimp@sandia.gov - - Copyright (2003) Sandia Corporation. Under the terms of Contract - DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains - certain rights in this software. This software is distributed under - the GNU General Public License. - - See the README file in the top-level LAMMPS directory. -------------------------------------------------------------------------- */ - -#include "neighbor.h" -#include "neigh_list.h" -#include "atom.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- - routines to create a stencil = list of bin offsets - stencil = bins whose closest corner to central bin is within cutoff - sx,sy,sz = bin bounds = furthest the stencil could possibly extend - 3d creates xyz stencil, 2d creates xy stencil - for half list with newton off: - stencil is all surrounding bins including self - regardless of triclinic - for half list with newton on: - stencil is bins to the "upper right" of central bin - stencil does not include self - for half list with triclinic: - stencil is all bins in z-plane of self and above, but not below - in 2d is all bins in y-plane of self and above, but not below - stencil includes self - for full list: - stencil is all surrounding bins including self - regardless of newton on/off or triclinic - for multi: - create one stencil for each atom type - stencil is same bin bounds as newton on/off, triclinic, half/full - cutoff is not cutneighmaxsq, but max cutoff for that atom type -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_2d_no_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j; - int *stencil = list->stencil; - int nstencil = 0; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_ghost_bin_2d_no_newton(NeighList *list, - int sx, int sy, int sz) -{ - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - int nstencil = 0; - - for (int j = -sy; j <= sy; j++) - for (int i = -sx; i <= sx; i++) - if (bin_distance(i,j,0) < cutneighmaxsq) { - stencilxyz[nstencil][0] = i; - stencilxyz[nstencil][1] = j; - stencilxyz[nstencil][2] = 0; - stencil[nstencil++] = j*mbinx + i; - } - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_3d_no_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k; - int *stencil = list->stencil; - int 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) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_ghost_bin_3d_no_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k; - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - int 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) { - stencilxyz[nstencil][0] = i; - stencilxyz[nstencil][1] = j; - stencilxyz[nstencil][2] = k; - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - } - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_2d_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j; - int *stencil = list->stencil; - int nstencil = 0; - - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_3d_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k; - int *stencil = list->stencil; - int nstencil = 0; - - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) - if (bin_distance(i,j,k) < cutneighmaxsq) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_2d_newton_tri(NeighList *list, - int sx, int sy, int sz) -{ - int i,j; - int *stencil = list->stencil; - int nstencil = 0; - - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_bin_3d_newton_tri(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k; - int *stencil = list->stencil; - int nstencil = 0; - - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,k) < cutneighmaxsq) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_multi_2d_no_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_multi_3d_no_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,k); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = k*mbiny*mbinx + j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_multi_2d_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (j > 0 || (j == 0 && i > 0)) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_multi_3d_newton(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (k > 0 || j > 0 || (j == 0 && i > 0)) { - rsq = bin_distance(i,j,k); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = k*mbiny*mbinx + j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_multi_2d_newton_tri(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (j = 0; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_half_multi_3d_newton_tri(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (k = 0; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,k); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = k*mbiny*mbinx + j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_bin_2d(NeighList *list, - int sx, int sy, int sz) -{ - int i,j; - int *stencil = list->stencil; - int nstencil = 0; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,0) < cutneighmaxsq) - stencil[nstencil++] = j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_ghost_bin_2d(NeighList *list, - int sx, int sy, int sz) -{ - int i,j; - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - int nstencil = 0; - - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) - if (bin_distance(i,j,0) < cutneighmaxsq) { - stencilxyz[nstencil][0] = i; - stencilxyz[nstencil][1] = j; - stencilxyz[nstencil][2] = 0; - stencil[nstencil++] = j*mbinx + i; - } - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_bin_3d(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k; - int *stencil = list->stencil; - int 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) - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_ghost_bin_3d(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k; - int *stencil = list->stencil; - int **stencilxyz = list->stencilxyz; - int 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) { - stencilxyz[nstencil][0] = i; - stencilxyz[nstencil][1] = j; - stencilxyz[nstencil][2] = k; - stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; - } - - list->nstencil = nstencil; -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_multi_2d(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,0); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} - -/* ---------------------------------------------------------------------- */ - -void Neighbor::stencil_full_multi_3d(NeighList *list, - int sx, int sy, int sz) -{ - int i,j,k,n; - double rsq,typesq; - int *s; - double *distsq; - - int *nstencil_multi = list->nstencil_multi; - int **stencil_multi = list->stencil_multi; - double **distsq_multi = list->distsq_multi; - - int ntypes = atom->ntypes; - for (int itype = 1; itype <= ntypes; itype++) { - typesq = cuttypesq[itype]; - s = stencil_multi[itype]; - distsq = distsq_multi[itype]; - n = 0; - for (k = -sz; k <= sz; k++) - for (j = -sy; j <= sy; j++) - for (i = -sx; i <= sx; i++) { - rsq = bin_distance(i,j,k); - if (rsq < typesq) { - distsq[n] = rsq; - s[n++] = k*mbiny*mbinx + j*mbinx + i; - } - } - nstencil_multi[itype] = n; - } -} diff --git a/src/neighbor.cpp b/src/neighbor.cpp index de6835da87..d014f1c8d0 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -22,6 +22,10 @@ #include "neighbor.h" #include "neigh_list.h" #include "neigh_request.h" +#include "style_nbin.h" +#include "style_nstencil.h" +#include "style_npair.h" +#include "style_ntopo.h" #include "atom.h" #include "atom_vec.h" #include "comm.h" @@ -39,17 +43,18 @@ #include "memory.h" #include "error.h" +#include + using namespace LAMMPS_NS; +using namespace NeighConst; #define RQDELTA 1 #define EXDELTA 1 -#define LB_FACTOR 1.5 -#define SMALL 1.0e-6 #define BIG 1.0e20 -#define CUT2BIN_RATIO 100 -enum{NSQ,BIN,MULTI}; // also in neigh_list.cpp +enum{NSQ,BIN,MULTI}; // also in NBin, NeighList, NStencil +enum{NONE,ALL,PARTIAL,TEMPLATE}; static const char cite_neigh_multi[] = "neighbor multi command:\n\n" @@ -73,6 +78,8 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) MPI_Comm_rank(world,&me); MPI_Comm_size(world,&nprocs); + firsttime = 1; + style = BIN; every = 1; delay = 10; @@ -82,7 +89,6 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) binsizeflag = 0; build_once = 0; cluster_check = 0; - binatomflag = 1; ago = -1; cutneighmax = 0.0; @@ -92,18 +98,60 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) cuttypesq = NULL; fixchecklist = NULL; + // pairwise neighbor lists and associated data structs + + nlist = 0; + lists = NULL; + + nbin = 0; + neigh_bin = NULL; + + nstencil = 0; + neigh_stencil = NULL; + + neigh_pair = NULL; + + nstencil_perpetual = 0; + slist = NULL; + + npair_perpetual = 0; + plist = NULL; + + nrequest = maxrequest = 0; + requests = NULL; + + old_nrequest = 0; + old_requests = NULL; + + old_style = style; + old_triclinic = 0; + old_pgsize = pgsize; + old_oneatom = oneatom; + + zeroes = NULL; + + binclass = NULL; + binnames = NULL; + binmasks = NULL; + stencilclass = NULL; + stencilnames = NULL; + stencilmasks = NULL; + + // topology lists + + bondwhich = anglewhich = dihedralwhich = improperwhich = NONE; + + neigh_bond = NULL; + neigh_angle = NULL; + neigh_dihedral = NULL; + neigh_improper = NULL; + // coords at last neighboring maxhold = 0; xhold = NULL; lastcall = -1; - - // binning - - maxhead = 0; - binhead = NULL; - maxbin = 0; - bins = NULL; + last_setup_bins = -1; // pair exclusion list info @@ -119,45 +167,7 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) nex_mol = maxex_mol = 0; ex_mol_group = ex_mol_bit = NULL; - // pair lists - - maxatom = 0; - nblist = nglist = nslist = 0; - - nlist = 0; - lists = NULL; - pair_build = NULL; - stencil_create = NULL; - blist = glist = slist = NULL; - anyghostlist = 0; - - nrequest = maxrequest = 0; - requests = NULL; - - old_nrequest = 0; - old_requests = NULL; - - old_style = style; - old_triclinic = 0; - old_pgsize = pgsize; - old_oneatom = oneatom; - old_every = every; - old_delay = delay; - old_check = dist_check; - old_cutoff = cutneighmax; - - zeroes = NULL; - - // bond lists - - maxbond = 0; - bondlist = NULL; - maxangle = 0; - anglelist = NULL; - maxdihedral = 0; - dihedrallist = NULL; - maximproper = 0; - improperlist = NULL; + // Kokkos setting copymode = 0; } @@ -174,10 +184,41 @@ Neighbor::~Neighbor() delete [] cuttypesq; delete [] fixchecklist; - memory->destroy(xhold); + for (int i = 0; i < nlist; i++) delete lists[i]; + for (int i = 0; i < nbin; i++) delete neigh_bin[i]; + for (int i = 0; i < nstencil; i++) delete neigh_stencil[i]; + for (int i = 0; i < nlist; i++) delete neigh_pair[i]; + delete [] lists; + delete [] neigh_bin; + delete [] neigh_stencil; + delete [] neigh_pair; - memory->destroy(binhead); - memory->destroy(bins); + delete [] slist; + delete [] plist; + + for (int i = 0; i < nrequest; i++) delete requests[i]; + memory->sfree(requests); + for (int i = 0; i < old_nrequest; i++) delete old_requests[i]; + memory->sfree(old_requests); + + delete [] zeroes; + + delete [] binclass; + delete [] binnames; + delete [] binmasks; + delete [] stencilclass; + delete [] stencilnames; + delete [] stencilmasks; + delete [] pairclass; + delete [] pairnames; + delete [] pairmasks; + + delete neigh_bond; + delete neigh_angle; + delete neigh_dihedral; + delete neigh_improper; + + memory->destroy(xhold); memory->destroy(ex1_type); memory->destroy(ex2_type); @@ -190,33 +231,13 @@ Neighbor::~Neighbor() memory->destroy(ex_mol_group); delete [] ex_mol_bit; - - for (int i = 0; i < nlist; i++) delete lists[i]; - delete [] lists; - delete [] pair_build; - delete [] stencil_create; - delete [] blist; - delete [] glist; - delete [] slist; - - for (int i = 0; i < nrequest; i++) delete requests[i]; - memory->sfree(requests); - for (int i = 0; i < old_nrequest; i++) delete old_requests[i]; - memory->sfree(old_requests); - - delete [] zeroes; - - memory->destroy(bondlist); - memory->destroy(anglelist); - memory->destroy(dihedrallist); - memory->destroy(improperlist); } /* ---------------------------------------------------------------------- */ void Neighbor::init() { - int i,j,m,n; + int i,j,n; ncalls = ndanger = 0; dimension = domain->dimension; @@ -234,7 +255,7 @@ void Neighbor::init() // ------------------------------------------------------------------ // settings - // bbox lo/hi = bounding box of entire domain, stored by Domain + // bbox lo/hi ptrs = bounding box of entire domain, stored by Domain if (triclinic == 0) { bboxlo = domain->boxlo; @@ -293,7 +314,23 @@ void Neighbor::init() } cutneighmaxsq = cutneighmax * cutneighmax; - // check other classes that can induce reneighboring in decide() + // rRESPA cutoffs + + int respa = 0; + if (update->whichflag == 1 && strstr(update->integrate_style,"respa")) { + if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; + if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; + } + + if (respa) { + double *cut_respa = ((Respa *) update->integrate)->cutoff; + cut_inner_sq = (cut_respa[1] + skin) * (cut_respa[1] + skin); + cut_middle_sq = (cut_respa[3] + skin) * (cut_respa[3] + skin); + cut_middle_inside_sq = (cut_respa[0] - skin) * (cut_respa[0] - skin); + if (cut_respa[0]-skin < 0) cut_middle_inside_sq = 0.0; + } + + // fixchecklist = other classes that can induce reneighboring in decide() restart_check = 0; if (output->restart_flag) restart_check = 1; @@ -347,26 +384,10 @@ void Neighbor::init() if (special_flag[2] == 2) maxwt = 3; if (special_flag[3] == 2) maxwt = 4; - // rRESPA cutoffs - - int respa = 0; - if (update->whichflag == 1 && strstr(update->integrate_style,"respa")) { - if (((Respa *) update->integrate)->level_inner >= 0) respa = 1; - if (((Respa *) update->integrate)->level_middle >= 0) respa = 2; - } - - if (respa) { - double *cut_respa = ((Respa *) update->integrate)->cutoff; - cut_inner_sq = (cut_respa[1] + skin) * (cut_respa[1] + skin); - cut_middle_sq = (cut_respa[3] + skin) * (cut_respa[3] + skin); - cut_middle_inside_sq = (cut_respa[0] - skin) * (cut_respa[0] - skin); - if (cut_respa[0]-skin < 0) cut_middle_inside_sq = 0.0; - } - // ------------------------------------------------------------------ - // xhold, bins, exclusion lists + // xhold array - // free xhold and bins if not needed for this run + // free if not needed for this run if (dist_check == 0) { memory->destroy(xhold); @@ -374,15 +395,7 @@ void Neighbor::init() xhold = NULL; } - if (style == NSQ) { - memory->destroy(bins); - memory->destroy(binhead); - maxbin = maxhead = 0; - binhead = NULL; - bins = NULL; - } - - // 1st time allocation of xhold and bins + // first time allocation if (dist_check) { if (maxhold == 0) { @@ -391,14 +404,10 @@ void Neighbor::init() } } - if (style != NSQ) { - if (maxbin == 0) { - maxbin = atom->nmax; - memory->create(bins,maxbin,"bins"); - } - } + // ------------------------------------------------------------------ + // exclusion lists - // exclusion lists for type, group, molecule settings from neigh_modify + // depend on type, group, molecule settings from neigh_modify // warn if exclusions used with KSpace solver n = atom->ntypes; @@ -460,18 +469,132 @@ void Neighbor::init() "may give inconsistent Coulombic energies"); // ------------------------------------------------------------------ - // pairwise lists + // create pairwise lists + // one-time call to init_styles() to scan style files and setup + // init_pair() creates auxiliary classes: NBin, NStencil, NPair + + if (firsttime) init_styles(); + firsttime = 0; + + init_pair(); + + // invoke copy_neighbor_info() in Bin,Stencil,Pair classes + // copied once per run in case any cutoff, exclusion, special info changed + + for (i = 0; i < nbin; i++) neigh_bin[i]->copy_neighbor_info(); + for (i = 0; i < nstencil; i++) neigh_stencil[i]->copy_neighbor_info(); + for (i = 0; i < nlist; i++) + if (neigh_pair[i]) neigh_pair[i]->copy_neighbor_info(); + + if (!same && comm->me == 0) print_pairwise_info(); + requests_new2old(); + + // ------------------------------------------------------------------ + // create topology lists + // instantiated topo styles can change from run to run + + init_topology(); +} + +/* ---------------------------------------------------------------------- + create and initialize lists of Nbin, Nstencil, NPair classes + lists have info on all classes in 3 style*.h files + cannot do this in constructor, b/c too early to instantiate classes +------------------------------------------------------------------------- */ + +void Neighbor::init_styles() +{ + // extract info from NBin classes listed in style_nbin.h + + nbclass = 0; + +#define NBIN_CLASS +#define NBinStyle(key,Class,bitmasks) nbclass++; +#include "style_nbin.h" +#undef NBinStyle +#undef NBIN_CLASS + + binclass = new BinCreator[nbclass]; + binnames = new char*[nbclass]; + binmasks = new int[nbclass]; + nbclass = 0; + +#define NBIN_CLASS +#define NBinStyle(key,Class,bitmasks) \ + binnames[nbclass] = (char *) #key; \ + binclass[nbclass] = &bin_creator; \ + binmasks[nbclass++] = bitmasks; +#include "style_nbin.h" +#undef NBinStyle +#undef NBIN_CLASS + + // extract info from NStencil classes listed in style_nstencil.h + + nsclass = 0; + +#define NSTENCIL_CLASS +#define NStencilStyle(key,Class,bitmasks) nsclass++; +#include "style_nstencil.h" +#undef NStencilStyle +#undef NSTENCIL_CLASS + + stencilclass = new StencilCreator[nsclass]; + stencilnames = new char*[nsclass]; + stencilmasks = new int[nsclass]; + nsclass = 0; + +#define NSTENCIL_CLASS +#define NStencilStyle(key,Class,bitmasks) \ + stencilnames[nsclass] = (char *) #key; \ + stencilclass[nsclass] = &stencil_creator; \ + stencilmasks[nsclass++] = bitmasks; +#include "style_nstencil.h" +#undef NStencilStyle +#undef NSTENCIL_CLASS + + // extract info from NPair classes listed in style_npair.h + + npclass = 0; + +#define NPAIR_CLASS +#define NPairStyle(key,Class,bitmasks) npclass++; +#include "style_npair.h" +#undef NPairStyle +#undef NPAIR_CLASS + + pairclass = new PairCreator[npclass]; + pairnames = new char*[npclass]; + pairmasks = new int[npclass]; + npclass = 0; + +#define NPAIR_CLASS +#define NPairStyle(key,Class,bitmasks) \ + pairnames[npclass] = (char *) #key; \ + pairclass[npclass] = &pair_creator; \ + pairmasks[npclass++] = bitmasks; +#include "style_npair.h" +#undef NPairStyle +#undef NPAIR_CLASS +} + +/* ---------------------------------------------------------------------- + create and initialize NPair classes +------------------------------------------------------------------------- */ + +void Neighbor::init_pair() +{ + int i,j,k,m; // test if pairwise lists need to be re-created // no need to re-create if: // neigh style, triclinic, pgsize, oneatom have not changed // current requests = old requests // first archive request params for current requests - // before Neighbor possibly changes them below + // before possibly changing them below for (i = 0; i < nrequest; i++) requests[i]->archive(); - int same = 1; + same = 1; if (style != old_style) same = 0; if (triclinic != old_triclinic) same = 0; if (pgsize != old_pgsize) same = 0; @@ -485,438 +608,341 @@ void Neighbor::init() if (comm->me == 0) printf("SAME flag %d\n",same); #endif - // if old and new are not the same, create new pairwise lists + if (same) return; + + // delete old lists and create new ones - if (!same) { + for (i = 0; i < nlist; i++) delete lists[i]; + for (i = 0; i < nbin; i++) delete neigh_bin[i]; + for (i = 0; i < nstencil; i++) delete neigh_stencil[i]; + for (i = 0; i < nlist; i++) delete neigh_pair[i]; + delete [] lists; + delete [] neigh_bin; + delete [] neigh_stencil; + delete [] neigh_pair; - // delete old lists and create new ones - - for (i = 0; i < nlist; i++) delete lists[i]; - delete [] lists; - delete [] pair_build; - delete [] stencil_create; - - if (lmp->kokkos) nlist = init_lists_kokkos(); - else nlist = nrequest; - - lists = new NeighList*[nrequest]; - pair_build = new PairPtr[nrequest]; - stencil_create = new StencilPtr[nrequest]; - - // initialize to NULL since some may be Kokkos lists - - for (i = 0; i < nrequest; i++) { - lists[i] = NULL; - pair_build[i] = NULL; - stencil_create[i] = NULL; - } - - // create individual lists, one per request - // pass list ptr back to requestor (except for Command class) - // wait to allocate initial pages until copy lists are detected - - for (i = 0; i < nrequest; i++) { - if (requests[i]->kokkos_host || requests[i]->kokkos_device) continue; + nlist = nrequest; + + lists = new NeighList*[nrequest]; + neigh_bin = new NBin*[nrequest]; + neigh_stencil = new NStencil*[nrequest]; + neigh_pair = new NPair*[nrequest]; + + // create individual lists, one per request + // pass list ptr back to requestor (except for Command class) + // wait to allocate initial pages until copy lists are detected + + for (i = 0; i < nrequest; i++) { + if (requests[i]->kokkos_host || requests[i]->kokkos_device) + create_kokkos_list(i); + else lists[i] = new NeighList(lmp); - lists[i]->index = i; + lists[i]->index = i; + + if (requests[i]->pair) { + Pair *pair = (Pair *) requests[i]->requestor; + pair->init_list(requests[i]->id,lists[i]); + } else if (requests[i]->fix) { + Fix *fix = (Fix *) requests[i]->requestor; + fix->init_list(requests[i]->id,lists[i]); + } else if (requests[i]->compute) { + Compute *compute = (Compute *) requests[i]->requestor; + compute->init_list(requests[i]->id,lists[i]); + } + } - if (requests[i]->pair) { - Pair *pair = (Pair *) requests[i]->requestor; - pair->init_list(requests[i]->id,lists[i]); - } else if (requests[i]->fix) { - Fix *fix = (Fix *) requests[i]->requestor; - fix->init_list(requests[i]->id,lists[i]); - } else if (requests[i]->compute) { - Compute *compute = (Compute *) requests[i]->requestor; - compute->init_list(requests[i]->id,lists[i]); + // morph requests via A,B,C rules + // this is to avoid duplicate or inefficient builds + // update both request and list when morph + + // (A) rule: + // invoke post_constructor() for all lists + // processes copy,skip,half_from_full,granhistory,respaouter lists + // error checks and resets internal ptrs to other lists that now exist + + for (i = 0; i < nrequest; i++) + lists[i]->post_constructor(requests[i]); + + // (B) rule: + // if request = pair, half, newton != 2 + // and full perpetual non-skip/copy list exists, + // then morph to half_from_full of matching parent list + // NOTE: should be OK if parent is skip list? + // see build method comments + // parent can be pair or fix, so long as perpetual fix + // NOTE: could remove newton != 2 restriction if added + // half_from_full_newtoff_ghost NPair class + // this would require full list having ghost info + // would be useful when reax/c used in hybrid mode, e.g. with airebo + + for (i = 0; i < nrequest; i++) { + if (requests[i]->pair && requests[i]->half && requests[i]->newton != 2) { + for (j = 0; j < nrequest; j++) { + // Kokkos doesn't yet support half from full + if (requests[i]->kokkos_device || requests[j]->kokkos_device) continue; + if (requests[i]->kokkos_host || requests[j]->kokkos_host) continue; + + if (requests[j]->full && requests[j]->occasional == 0 && + !requests[j]->skip && !requests[j]->copy) break; + } + if (j < nrequest) { + requests[i]->half = 0; + requests[i]->half_from_full = 1; + lists[i]->listfull = lists[j]; } } + } + + // (C) rule: + // for fix/compute requests, occasional or not does not matter + // 1st check: + // if request = half and non-skip/copy pair half/respaouter request exists, + // or if request = full and non-skip/copy pair full request exists, + // or if request = gran and non-skip/copy pair gran request exists, + // then morph to copy of the matching parent list + // 2nd check: only if no match to 1st check + // if request = half and non-skip/copy pair full request exists, + // then morph to half_from_full of the matching parent list + // for 1st or 2nd check, parent can be copy list or pair or fix + + for (i = 0; i < nrequest; i++) { + if (!requests[i]->fix && !requests[i]->compute) continue; + for (j = 0; j < nrequest; j++) { + // Kokkos flags must match + if (requests[i]->kokkos_device != requests[j]->kokkos_device) continue; + if (requests[i]->kokkos_host != requests[j]->kokkos_host) continue; - // detect lists that are connected to other lists - // if-then-else sequence and processed flag is important - // since don't want to re-process skip or copy lists further down + if (requests[i]->ssa != requests[j]->ssa) continue; - int processed; - - for (i = 0; i < nrequest; i++) { - if (!lists[i]) continue; - processed = 0; - - // copy: point this list at request->otherlist, could be a skip list - - if (requests[i]->copy) { - lists[i]->listcopy = lists[requests[i]->otherlist]; - processed = 1; - - // skip: point this list at request->otherlist, - // copy skip info from request - // skip list still needs to have granhistory or respa info added below - - } else if (requests[i]->skip) { - lists[i]->listskip = lists[requests[i]->otherlist]; - lists[i]->copy_skip_info(requests[i]->iskip,requests[i]->ijskip); - processed = 1; - - // half_from_full: point this list at full list that comes right before - // will only be case if pair style requested one after other - - } else if (requests[i]->half_from_full) { - lists[i]->listfull = lists[i-1]; - processed = 1; - } - - // granhistory: set preceeding list's listgranhistory to this list - // also set FH ptr in preceeding list to FSH class created by pair - - if (requests[i]->granhistory) { - lists[i-1]->listgranhistory = lists[i]; - lists[i-1]->fix_history = requests[i]->fix_history; - processed = 1; - - // respaouter: point this list at preceeding 1/2 inner/middle lists - - } else if (requests[i]->respaouter) { - if (requests[i-1]->respainner) { - lists[i]->respamiddle = 0; - lists[i]->listinner = lists[i-1]; - } else { - lists[i]->respamiddle = 1; - lists[i]->listmiddle = lists[i-1]; - lists[i]->listinner = lists[i-2]; - } - processed = 1; - } - - if (processed) continue; - - // pair and half and newton != 2: - // if there is a full non-occasional non-skip list - // change this list to half_from_full and point at the full list - // parent could be copy list or pair or fix - // could remove newton != 2 check if added half_from_full_no_newton_ghost - // option in neigh_derive.cpp and below in choose_build() - // this would require full list had ghost info - // would be useful when reax/c used in hybrid mode, e.g. with airebo - - if (requests[i]->pair && requests[i]->half && requests[i]->newton != 2) { - for (j = 0; j < nrequest; j++) { - if (!lists[j]) continue; - if (requests[j]->full && requests[j]->occasional == 0 && - requests[j]->skip == 0) break; - } - if (j < nrequest) { - requests[i]->half = 0; - requests[i]->half_from_full = 1; - lists[i]->listfull = lists[j]; - } - - // fix/compute requests: - // whether request is occasional or not doesn't matter - // if request = half and non-skip pair half/respaouter exists, - // if request = full and non-skip pair full exists, - // if request = half and non-skip pair full exists, - // if no matches, do nothing - // fix/compute list will be built independently as needed - // ok if parent is itself a copy list - - } else if (requests[i]->fix || requests[i]->compute) { - for (j = 0; j < nrequest; j++) { - if (!lists[j]) continue; - if (requests[i]->half && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->half) break; - if (requests[i]->full && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->full) break; - if (requests[i]->gran && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->gran) break; - if (requests[i]->half && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->respaouter) break; - } - if (j < nrequest) { - requests[i]->copy = 1; - requests[i]->otherlist = j; - lists[i]->listcopy = lists[j]; - } else { - for (j = 0; j < nrequest; j++) { - if (!lists[j]) continue; - if (requests[i]->half && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->full) break; - } - if (j < nrequest) { - requests[i]->half = 0; - requests[i]->half_from_full = 1; - lists[i]->listfull = lists[j]; - } - } - } + if (requests[i]->half && requests[j]->pair && + !requests[j]->skip && requests[j]->half && !requests[j]->copy) + break; + if (requests[i]->half && requests[j]->pair && + !requests[j]->skip && requests[j]->respaouter && !requests[j]->copy) + break; + if (requests[i]->full && requests[j]->pair && + !requests[j]->skip && requests[j]->full && !requests[j]->copy) + break; + if (requests[i]->gran && requests[j]->pair && + !requests[j]->skip && requests[j]->gran && !requests[j]->copy) + break; } - - // allocate initial pages for each list, except if listcopy set - // allocate dnum vector of zeroes if set - - int dnummax = 0; - for (i = 0; i < nrequest; i++) { - if (!lists[i]) continue; - if (!lists[i]->listcopy) { - lists[i]->setup_pages(pgsize,oneatom,requests[i]->dnum); - dnummax = MAX(dnummax,requests[i]->dnum); - } + if (j < nrequest) { + requests[i]->copy = 1; + requests[i]->otherlist = j; + lists[i]->copy = 1; + lists[i]->listcopy = lists[j]; + continue; } + for (j = 0; j < nrequest; j++) { + // Kokkos doesn't yet support half from full + if (requests[i]->kokkos_device || requests[j]->kokkos_device) continue; + if (requests[i]->kokkos_host || requests[j]->kokkos_host) continue; - if (dnummax) { - delete [] zeroes; - zeroes = new double[dnummax]; - for (i = 0; i < dnummax; i++) zeroes[i] = 0.0; + if (requests[i]->half && requests[j]->pair && + !requests[j]->skip && requests[j]->full && !requests[j]->copy) + break; } - - // set ptrs to pair_build and stencil_create functions for each list - // ptrs set to NULL if not set explicitly - - for (i = 0; i < nrequest; i++) { - choose_build(i,requests[i]); - if (style != NSQ) choose_stencil(i,requests[i]); - else stencil_create[i] = NULL; + if (j < nrequest) { + requests[i]->half = 0; + requests[i]->half_from_full = 1; + lists[i]->listfull = lists[j]; } + } - // set each list's build/grow/stencil/ghost flags based on neigh request - // buildflag = 1 if its pair_build() invoked every reneighbor - // growflag = 1 if it stores atom-based arrays and pages - // stencilflag = 1 if it stores stencil arrays - // ghostflag = 1 if it stores neighbors of ghosts - // anyghostlist = 1 if any non-occasional list stores neighbors of ghosts + // assign Bin,Stencil,Pair style to each list + + int flag; + for (i = 0; i < nrequest; i++) { + flag = choose_bin(requests[i]); + lists[i]->bin_method = flag; + if (flag < 0) + error->all(FLERR,"Requested neighbor bin option does not exist"); - anyghostlist = 0; - int anybuild = 0; + flag = choose_stencil(requests[i]); + lists[i]->stencil_method = flag; + if (flag < 0) + error->all(FLERR,"Requested neighbor stencil method does not exist"); - for (i = 0; i < nrequest; i++) { - if (lists[i]) { - lists[i]->buildflag = 1; - if (pair_build[i] == NULL) lists[i]->buildflag = 0; - if (requests[i]->occasional) lists[i]->buildflag = 0; - if (lists[i]->buildflag) anybuild = 1; + flag = choose_pair(requests[i]); + lists[i]->pair_method = flag; + if (flag < 0) + error->all(FLERR,"Requested neighbor pair method does not exist"); + } - lists[i]->growflag = 1; - if (requests[i]->copy) lists[i]->growflag = 0; + // instantiate unique Bin,Stencil classes in neigh_bin & neigh_stencil vecs + // instantiate one Pair class per list in neigh_pair vec - lists[i]->stencilflag = 1; - if (style == NSQ) lists[i]->stencilflag = 0; - if (stencil_create[i] == NULL) lists[i]->stencilflag = 0; + nbin = 0; + for (i = 0; i < nrequest; i++) { + flag = lists[i]->bin_method; + if (flag == 0) continue; + for (j = 0; j < nbin; j++) + if (neigh_bin[j]->istyle == flag) break; + if (j < nbin) continue; + BinCreator bin_creator = binclass[flag-1]; + neigh_bin[nbin] = bin_creator(lmp); + neigh_bin[nbin]->istyle = flag; + nbin++; + } - lists[i]->ghostflag = 0; - if (requests[i]->ghost) lists[i]->ghostflag = 1; - if (requests[i]->ghost && !requests[i]->occasional) anyghostlist = 1; - - lists[i]->ssaflag = 0; - if (requests[i]->ssa) lists[i]->ssaflag = 1; - } else init_list_flags1_kokkos(i); - } - - // no request has the buildflag set, so set it for the first request only - // this insure binning is done for any occasional neighbor lists - - if (!anybuild) { - for (i = 0; i < nrequest; i++) { - if (lists[i]) { - lists[i]->buildflag = 1; - break; - } - } - } - -#ifdef NEIGH_LIST_DEBUG - for (i = 0; i < nrequest; i++) - if (comm->me == 0) printf("Build/stencil methods: %d: %p %p\n", - i,pair_build[i],stencil_create[i]); - for (i = 0; i < nrequest; i++) lists[i]->print_attributes(); -#endif - - // allocate atom arrays for neighbor lists that store them - - maxatom = atom->nmax; - for (i = 0; i < nrequest; i++) { - if (lists[i]) { - if (lists[i]->growflag) lists[i]->grow(maxatom); - } else init_list_grow_kokkos(i); - } - - // setup 3 vectors of pairwise neighbor lists - // blist = lists whose pair_build() is invoked every reneighbor - // glist = lists who store atom arrays which are used every reneighbor - // slist = lists who store stencil arrays which are used every reneighbor - // blist and glist vectors are used by neighbor::build() - // slist vector is used by neighbor::setup_bins() - - nblist = nglist = nslist = 0; - delete [] blist; - delete [] glist; - delete [] slist; - blist = new int[nrequest]; - glist = new int[nrequest]; - slist = new int[nrequest]; - - for (i = 0; i < nrequest; i++) { - if (lists[i]) { - if (lists[i]->buildflag) blist[nblist++] = i; - if (lists[i]->growflag && requests[i]->occasional == 0) - glist[nglist++] = i; - if (lists[i]->stencilflag && requests[i]->occasional == 0) - slist[nslist++] = i; - } else init_list_flags2_kokkos(i); - } - - // no request had buildflag set, so we set it for the first request - // we also need to set other occasional neighbor list properties - - if (!anybuild) - for (i = 0; i < nrequest; i++) - if (lists[i] && lists[i]->buildflag) { - if (lists[i]->growflag) glist[nglist++] = i; - if (lists[i]->stencilflag) slist[nslist++] = i; - } - -#ifdef NEIGH_LIST_DEBUG - print_lists_of_lists(); -#endif - - // reorder build vector if necessary - // relevant for lists that copy/skip/half-full from parent - // the derived list must appear in blist after the parent list - // no occasional lists are in build vector - // swap two lists within blist when dependency is mis-ordered - // done when entire pass thru blist results in no swaps - - int done = 0; - while (!done) { - done = 1; - for (i = 0; i < nblist; i++) { - if (!lists[blist[i]]) continue; - NeighList *ptr = NULL; - if (lists[blist[i]]->listfull) ptr = lists[blist[i]]->listfull; - if (lists[blist[i]]->listcopy) ptr = lists[blist[i]]->listcopy; - if (lists[blist[i]]->listskip) ptr = lists[blist[i]]->listskip; - if (ptr == NULL) continue; - for (m = 0; m < nrequest; m++) - if (ptr == lists[m]) break; - for (j = 0; j < nblist; j++) - if (m == blist[j]) break; - if (j < i) continue; - int tmp = blist[i]; - blist[i] = blist[j]; - blist[j] = tmp; - done = 0; + nstencil = 0; + for (i = 0; i < nrequest; i++) { + flag = lists[i]->stencil_method; + if (flag == 0) continue; + for (j = 0; j < nstencil; j++) + if (neigh_stencil[j]->istyle == flag) break; + if (j < nstencil) continue; + StencilCreator stencil_creator = stencilclass[flag-1]; + neigh_stencil[nstencil] = stencil_creator(lmp); + neigh_stencil[nstencil]->istyle = flag; + int bin_method = lists[i]->bin_method; + for (k = 0; k < nbin; k++) { + if (neigh_bin[k]->istyle == bin_method) { + neigh_stencil[nstencil]->nb = neigh_bin[k]; break; } } - -#ifdef NEIGH_LIST_DEBUG - print_lists_of_lists(); -#endif + if (k == nbin) + error->all(FLERR,"Could not assign bin method to neighbor stencil"); + nstencil++; } - // output neighbor list info, only first time or when info changes + for (i = 0; i < nrequest; i++) { + flag = lists[i]->pair_method; + if (flag == 0) { + neigh_pair[i] = NULL; + continue; + } + PairCreator pair_creator = pairclass[flag-1]; + neigh_pair[i] = pair_creator(lmp); + neigh_pair[i]->istyle = flag; - if (!same || every != old_every || delay != old_delay || - old_check != dist_check || old_cutoff != cutneighmax) { - if (me == 0) { - const double cutghost = MAX(cutneighmax,comm->cutghostuser); - - double binsize, bbox[3]; - bbox[0] = bboxhi[0]-bboxlo[0]; - bbox[1] = bboxhi[1]-bboxlo[1]; - bbox[2] = bboxhi[2]-bboxlo[2]; - if (binsizeflag) binsize = binsize_user; - else if (style == BIN) binsize = 0.5*cutneighmax; - else binsize = 0.5*cutneighmin; - if (binsize == 0.0) binsize = bbox[0]; - - if (logfile) { - fprintf(logfile,"Neighbor list info ...\n"); - fprintf(logfile," %d neighbor list requests\n",nrequest); - fprintf(logfile," update every %d steps, delay %d steps, check %s\n", - every,delay,dist_check ? "yes" : "no"); - fprintf(logfile," max neighbors/atom: %d, page size: %d\n", - oneatom, pgsize); - fprintf(logfile," master list distance cutoff = %g\n",cutneighmax); - fprintf(logfile," ghost atom cutoff = %g\n",cutghost); - if (style != NSQ) - fprintf(logfile," binsize = %g -> bins = %g %g %g\n",binsize, - ceil(bbox[0]/binsize), ceil(bbox[1]/binsize), - ceil(bbox[2]/binsize)); + int bin_method = lists[i]->bin_method; + if (bin_method == 0) neigh_pair[i]->nb = NULL; + else { + for (k = 0; k < nbin; k++) { + if (neigh_bin[k]->istyle == bin_method) { + neigh_pair[i]->nb = neigh_bin[k]; + break; + } } - if (screen) { - fprintf(screen,"Neighbor list info ...\n"); - fprintf(screen," %d neighbor list requests\n",nrequest); - fprintf(screen," update every %d steps, delay %d steps, check %s\n", - every,delay,dist_check ? "yes" : "no"); - fprintf(screen," max neighbors/atom: %d, page size: %d\n", - oneatom, pgsize); - fprintf(screen," master list distance cutoff = %g\n",cutneighmax); - fprintf(screen," ghost atom cutoff = %g\n",cutghost); - if (style != NSQ) - fprintf(screen," binsize = %g, bins = %g %g %g\n",binsize, - ceil(bbox[0]/binsize), ceil(bbox[1]/binsize), - ceil(bbox[2]/binsize)); + if (k == nbin) + error->all(FLERR,"Could not assign bin method to neighbor pair"); + } + int stencil_method = lists[i]->stencil_method; + if (stencil_method == 0) neigh_pair[i]->ns = NULL; + else { + for (k = 0; k < nstencil; k++) { + if (neigh_stencil[k]->istyle == stencil_method) { + neigh_pair[i]->ns = neigh_stencil[k]; + break; + } } + if (k == nstencil) + error->all(FLERR,"Could not assign stencil method to neighbor pair"); } } - // mark all current requests as processed - // delete old requests - // copy current requests and style to old for next run - - for (i = 0; i < nrequest; i++) requests[i]->unprocessed = 0; - for (i = 0; i < old_nrequest; i++) delete old_requests[i]; - memory->sfree(old_requests); - - old_nrequest = nrequest; - old_requests = requests; - nrequest = maxrequest = 0; - requests = NULL; - old_style = style; - old_triclinic = triclinic; - old_pgsize = pgsize; - old_oneatom = oneatom; - old_every = every; - old_delay = delay; - old_check = dist_check; - old_cutoff = cutneighmax; - - // ------------------------------------------------------------------ - // topology lists - - // 1st time allocation of topology lists - - if (lmp->kokkos) { - init_topology_kokkos(); - return; + // allocate initial pages for each list, except if copy flag set + // allocate dnum vector of zeroes if set + + int dnummax = 0; + for (i = 0; i < nlist; i++) { + if (lists[i]->copy) continue; + lists[i]->setup_pages(pgsize,oneatom); + dnummax = MAX(dnummax,lists[i]->dnum); + } + + if (dnummax) { + delete [] zeroes; + zeroes = new double[dnummax]; + for (i = 0; i < dnummax; i++) zeroes[i] = 0.0; } - if (atom->molecular && atom->nbonds && maxbond == 0) { - if (nprocs == 1) maxbond = atom->nbonds; - else maxbond = static_cast (LB_FACTOR * atom->nbonds / nprocs); - memory->create(bondlist,maxbond,3,"neigh:bondlist"); + // first-time allocation of per-atom data for lists that are built and store + // lists that are not built: granhistory, respa inner/middle (no neigh_pair) + // lists that do not store: copy + // use atom->nmax for both grow() args + // i.e. grow first time to expanded size to avoid future reallocs + // also Kokkos list initialization + + int maxatom = atom->nmax; + for (i = 0; i < nlist; i++) + if (neigh_pair[i] && !lists[i]->copy) lists[i]->grow(maxatom,maxatom); + + // plist = indices of perpetual NPair classes + // perpetual = non-occasional, re-built at every reneighboring + // slist = indices of perpetual NStencil classes + // perpetual = used by any perpetual NPair class + + delete [] slist; + delete [] plist; + nstencil_perpetual = npair_perpetual = 0; + slist = new int[nstencil]; + plist = new int[nlist]; + + for (i = 0; i < nlist; i++) { + if (lists[i]->occasional == 0 && lists[i]->pair_method) + plist[npair_perpetual++] = i; + } + + for (i = 0; i < nstencil; i++) { + flag = 0; + for (j = 0; j < npair_perpetual; j++) + if (lists[plist[j]]->stencil_method == neigh_stencil[i]->istyle) flag = 1; + if (flag) slist[nstencil_perpetual++] = i; } - if (atom->molecular && atom->nangles && maxangle == 0) { - if (nprocs == 1) maxangle = atom->nangles; - else maxangle = static_cast (LB_FACTOR * atom->nangles / nprocs); - memory->create(anglelist,maxangle,4,"neigh:anglelist"); + // reorder plist vector if necessary + // relevant for lists that copy/skip/half-full from parent + // the child index must appear in plist after the parent index + // swap two indices within plist when dependency is mis-ordered + // done when entire pass thru plist results in no swaps + + NeighList *ptr; + + int done = 0; + while (!done) { + done = 1; + for (i = 0; i < npair_perpetual; i++) { + ptr = NULL; + if (lists[plist[i]]->listcopy) ptr = lists[plist[i]]->listcopy; + if (lists[plist[i]]->listskip) ptr = lists[plist[i]]->listskip; + if (lists[plist[i]]->listfull) ptr = lists[plist[i]]->listfull; + if (ptr == NULL) continue; + for (m = 0; m < nrequest; m++) + if (ptr == lists[m]) break; + for (j = 0; j < npair_perpetual; j++) + if (m == plist[j]) break; + if (j < i) continue; + int tmp = plist[i]; // swap I,J indices + plist[i] = plist[j]; + plist[j] = tmp; + done = 0; + break; + } } - if (atom->molecular && atom->ndihedrals && maxdihedral == 0) { - if (nprocs == 1) maxdihedral = atom->ndihedrals; - else maxdihedral = static_cast - (LB_FACTOR * atom->ndihedrals / nprocs); - memory->create(dihedrallist,maxdihedral,5,"neigh:dihedrallist"); - } + // debug output - if (atom->molecular && atom->nimpropers && maximproper == 0) { - if (nprocs == 1) maximproper = atom->nimpropers; - else maximproper = static_cast - (LB_FACTOR * atom->nimpropers / nprocs); - memory->create(improperlist,maximproper,5,"neigh:improperlist"); - } +#ifdef NEIGH_LIST_DEBUG + for (i = 0; i < nrequest; i++) lists[i]->print_attributes(); +#endif +} - // set flags that determine which topology neighboring routines to use +/* ---------------------------------------------------------------------- + create and initialize NTopo classes +------------------------------------------------------------------------- */ + +void Neighbor::init_topology() +{ + int i,m; + + if (!atom->molecular) return; + + // set flags that determine which topology neighbor classes to use + // these settings could change from run to run, depending on fixes defined // bonds,etc can only be broken for atom->molecular = 1, not 2 // SHAKE sets bonds and angles negative // gcmc sets all bonds, angles, etc negative @@ -971,40 +997,504 @@ void Neighbor::init() // sync on/off settings across all procs - int on_or_off = bond_off; - MPI_Allreduce(&on_or_off,&bond_off,1,MPI_INT,MPI_MAX,world); - on_or_off = angle_off; - MPI_Allreduce(&on_or_off,&angle_off,1,MPI_INT,MPI_MAX,world); - on_or_off = dihedral_off; - MPI_Allreduce(&on_or_off,&dihedral_off,1,MPI_INT,MPI_MAX,world); - on_or_off = improper_off; - MPI_Allreduce(&on_or_off,&improper_off,1,MPI_INT,MPI_MAX,world); + int onoff = bond_off; + MPI_Allreduce(&onoff,&bond_off,1,MPI_INT,MPI_MAX,world); + onoff = angle_off; + MPI_Allreduce(&onoff,&angle_off,1,MPI_INT,MPI_MAX,world); + onoff = dihedral_off; + MPI_Allreduce(&onoff,&dihedral_off,1,MPI_INT,MPI_MAX,world); + onoff = improper_off; + MPI_Allreduce(&onoff,&improper_off,1,MPI_INT,MPI_MAX,world); - // set ptrs to topology build functions + // instantiate NTopo classes - if (atom->molecular == 2) bond_build = &Neighbor::bond_template; - else if (bond_off) bond_build = &Neighbor::bond_partial; - else bond_build = &Neighbor::bond_all; + if (atom->avec->bonds_allow) { + int old_bondwhich = bondwhich; + if (atom->molecular == 2) bondwhich = TEMPLATE; + else if (bond_off) bondwhich = PARTIAL; + else bondwhich = ALL; + if (!neigh_bond || bondwhich != old_bondwhich) { + delete neigh_bond; + if (bondwhich == ALL) + neigh_bond = new NTopoBondAll(lmp); + else if (bondwhich == PARTIAL) + neigh_bond = new NTopoBondPartial(lmp); + else if (bondwhich == TEMPLATE) + neigh_bond = new NTopoBondTemplate(lmp); + } + } - if (atom->molecular == 2) angle_build = &Neighbor::angle_template; - else if (angle_off) angle_build = &Neighbor::angle_partial; - else angle_build = &Neighbor::angle_all; + if (atom->avec->angles_allow) { + int old_anglewhich = anglewhich; + if (atom->molecular == 2) anglewhich = TEMPLATE; + else if (angle_off) anglewhich = PARTIAL; + else anglewhich = ALL; + if (!neigh_angle || anglewhich != old_anglewhich) { + delete neigh_angle; + if (anglewhich == ALL) + neigh_angle = new NTopoAngleAll(lmp); + else if (anglewhich == PARTIAL) + neigh_angle = new NTopoAnglePartial(lmp); + else if (anglewhich == TEMPLATE) + neigh_angle = new NTopoAngleTemplate(lmp); + } + } - if (atom->molecular == 2) dihedral_build = &Neighbor::dihedral_template; - else if (dihedral_off) dihedral_build = &Neighbor::dihedral_partial; - else dihedral_build = &Neighbor::dihedral_all; + if (atom->avec->dihedrals_allow) { + int old_dihedralwhich = dihedralwhich; + if (atom->molecular == 2) dihedralwhich = TEMPLATE; + else if (dihedral_off) dihedralwhich = PARTIAL; + else dihedralwhich = ALL; + if (!neigh_dihedral || dihedralwhich != old_dihedralwhich) { + delete neigh_dihedral; + if (dihedralwhich == ALL) + neigh_dihedral = new NTopoDihedralAll(lmp); + else if (dihedralwhich == PARTIAL) + neigh_dihedral = new NTopoDihedralPartial(lmp); + else if (dihedralwhich == TEMPLATE) + neigh_dihedral = new NTopoDihedralTemplate(lmp); + } + } - if (atom->molecular == 2) improper_build = &Neighbor::improper_template; - else if (improper_off) improper_build = &Neighbor::improper_partial; - else improper_build = &Neighbor::improper_all; - - // set topology neighbor list counts to 0 - // in case all are turned off but potential is still defined - - nbondlist = nanglelist = ndihedrallist = nimproperlist = 0; + if (atom->avec->impropers_allow) { + int old_improperwhich = improperwhich; + if (atom->molecular == 2) improperwhich = TEMPLATE; + else if (improper_off) improperwhich = PARTIAL; + else improperwhich = ALL; + if (!neigh_improper || improperwhich != old_improperwhich) { + delete neigh_improper; + if (improperwhich == ALL) + neigh_improper = new NTopoImproperAll(lmp); + else if (improperwhich == PARTIAL) + neigh_improper = new NTopoImproperPartial(lmp); + else if (improperwhich == TEMPLATE) + neigh_improper = new NTopoImproperTemplate(lmp); + } + } } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + output summary of pairwise neighbor list info + only called by proc 0 +------------------------------------------------------------------------- */ + +void Neighbor::print_pairwise_info() +{ + int i,j,m; + char str[128]; + const char *kind; + FILE *out; + + const double cutghost = MAX(cutneighmax,comm->cutghostuser); + + double binsize, bbox[3]; + bbox[0] = bboxhi[0]-bboxlo[0]; + bbox[1] = bboxhi[1]-bboxlo[1]; + bbox[2] = bboxhi[2]-bboxlo[2]; + if (binsizeflag) binsize = binsize_user; + else if (style == BIN) binsize = 0.5*cutneighmax; + else binsize = 0.5*cutneighmin; + if (binsize == 0.0) binsize = bbox[0]; + + int nperpetual = 0; + int noccasional = 0; + int nextra = 0; + for (i = 0; i < nlist; i++) { + if (lists[i]->pair_method == 0) nextra++; + else if (lists[i]->occasional) noccasional++; + else nperpetual++; + } + + for (m = 0; m < 2; m++) { + if (m == 0) out = screen; + else out = logfile; + + if (out) { + fprintf(out,"Neighbor list info ...\n"); + fprintf(out," update every %d steps, delay %d steps, check %s\n", + every,delay,dist_check ? "yes" : "no"); + fprintf(out," max neighbors/atom: %d, page size: %d\n", + oneatom, pgsize); + fprintf(out," master list distance cutoff = %g\n",cutneighmax); + fprintf(out," ghost atom cutoff = %g\n",cutghost); + if (style != NSQ) + fprintf(out," binsize = %g, bins = %g %g %g\n",binsize, + ceil(bbox[0]/binsize), ceil(bbox[1]/binsize), + ceil(bbox[2]/binsize)); + + fprintf(out," %d neighbor lists, " + "perpetual/occasional/extra = %d %d %d\n", + nlist,nperpetual,noccasional,nextra); + + for (i = 0; i < nlist; i++) { + if (requests[i]->pair) { + char *pname = force->pair_match_ptr((Pair *) requests[i]->requestor); + sprintf(str," (%d) pair %s",i+1,pname); + } else if (requests[i]->fix) { + sprintf(str," (%d) fix %s",i+1, + ((Fix *) requests[i]->requestor)->style); + } else if (requests[i]->compute) { + sprintf(str," (%d) compute %s",i+1, + ((Compute *) requests[i]->requestor)->style); + } else { + sprintf(str," (%d) command %s",i+1,requests[i]->command_style); + } + fprintf(out,"%s\n",str); + + if (requests[i]->half) kind = "half"; + else if (requests[i]->full) kind = "full"; + else if (requests[i]->gran) kind = "size"; + else if (requests[i]->granhistory) kind = "size/history"; + else if (requests[i]->respainner) kind = "respa/inner"; + else if (requests[i]->respamiddle) kind = "respa/middle"; + else if (requests[i]->respaouter) kind = "respa/outer"; + else if (requests[i]->half_from_full) kind = "half/from/full"; + if (requests[i]->occasional) fprintf(out,", occasional"); + else fprintf(out,", perpetual"); + if (requests[i]->ghost) fprintf(out,", ghost"); + if (requests[i]->ssa) fprintf(out,", ssa"); + if (requests[i]->omp) fprintf(out,", omp"); + if (requests[i]->intel) fprintf(out,", intel"); + if (requests[i]->kokkos_device) fprintf(out,", kokkos_device"); + if (requests[i]->kokkos_host) fprintf(out,", kokkos_host"); + if (requests[i]->copy) + fprintf(out,", copy from (%d)",requests[i]->otherlist+1); + if (requests[i]->skip) + fprintf(out,", skip from (%d)",requests[i]->otherlist+1); + if (requests[i]->off2on) fprintf(out,", off2on"); + fprintf(out,"\n"); + + if (lists[i]->pair_method == 0) fprintf(out," pair build: none\n"); + else fprintf(out," pair build: %s\n", + pairnames[lists[i]->pair_method-1]); + + if (lists[i]->stencil_method == 0) fprintf(out," stencil: none\n"); + else fprintf(out," stencil: %s\n", + stencilnames[lists[i]->stencil_method-1]); + + if (lists[i]->bin_method == 0) fprintf(out," bin: none\n"); + else fprintf(out," bin: %s\n",binnames[lists[i]->bin_method-1]); + } + + /* + fprintf(out," %d stencil methods\n",nstencil); + for (i = 0; i < nstencil; i++) + fprintf(out," (%d) %s\n", + i+1,stencilnames[neigh_stencil[i]->istyle-1]); + + fprintf(out," %d bin methods\n",nbin); + for (i = 0; i < nbin; i++) + fprintf(out," (%d) %s\n",i+1,binnames[neigh_bin[i]->istyle-1]); + */ + } + } +} + +/* ---------------------------------------------------------------------- + delete old NeighRequests + copy current requests and params to old for next run +------------------------------------------------------------------------- */ + +void Neighbor::requests_new2old() +{ + for (int i = 0; i < old_nrequest; i++) delete old_requests[i]; + memory->sfree(old_requests); + + old_nrequest = nrequest; + old_requests = requests; + nrequest = maxrequest = 0; + requests = NULL; + old_style = style; + old_triclinic = triclinic; + old_pgsize = pgsize; + old_oneatom = oneatom; +} + +/* ---------------------------------------------------------------------- + assign NBin class to a NeighList + use neigh request settings to build mask + match mask to list of masks of known Nbin classes + return index+1 of match in list of masks + return 0 for no binning + return -1 if no match +------------------------------------------------------------------------- */ + +int Neighbor::choose_bin(NeighRequest *rq) +{ + // no binning needed + + if (style == NSQ) return 0; + if (rq->skip || rq->copy || rq->half_from_full) return 0; + if (rq->granhistory) return 0; + if (rq->respainner || rq->respamiddle) return 0; + + // flags for settings the request + system requires of NBin class + // ssaflag = no/yes ssa request + // intelflag = no/yes intel request + // kokkos_device_flag = no/yes kokkos device request + // kokkos_host_flag = no/yes kokkos host request + + int ssaflag,intelflag,kokkos_device_flag,kokkos_host_flag; + + ssaflag = intelflag = kokkos_device_flag = kokkos_host_flag = 0; + + if (rq->ssa) ssaflag = NB_SSA; + if (rq->intel) intelflag = NB_INTEL; + if (rq->kokkos_device) kokkos_device_flag = NB_KOKKOS_DEVICE; + if (rq->kokkos_host) kokkos_host_flag = NB_KOKKOS_HOST; + + // use flags to match exactly one of NBin class masks, bit by bit + + int mask; + + for (int i = 0; i < nbclass; i++) { + mask = binmasks[i]; + + if (ssaflag != (mask & NB_SSA)) continue; + if (intelflag != (mask & NB_INTEL)) continue; + if (kokkos_device_flag != (mask & NB_KOKKOS_DEVICE)) continue; + if (kokkos_host_flag != (mask & NB_KOKKOS_HOST)) continue; + + return i+1; + } + + // error return if matched none + + return -1; +} + +/* ---------------------------------------------------------------------- + assign NStencil class to a NeighList + use neigh request settings to build mask + match mask to list of masks of known NStencil classes + return index+1 of match in list of masks + return 0 for no binning + return -1 if no match +------------------------------------------------------------------------- */ + +int Neighbor::choose_stencil(NeighRequest *rq) +{ + // no stencil creation needed + + if (style == NSQ) return 0; + if (rq->skip || rq->copy || rq->half_from_full) return 0; + if (rq->granhistory) return 0; + if (rq->respainner || rq->respamiddle) return 0; + + // flags for settings the request + system requires of NStencil class + // halfflag = half request (gran and respa are also half lists) + // fullflag = full request + // ghostflag = no/yes ghost request + // ssaflag = no/yes ssa request + // dimension = 2d/3d + // newtflag = newton off/on request + // triclinic = orthgonal/triclinic box + + int halfflag,fullflag,ghostflag,ssaflag; + + halfflag = fullflag = ghostflag = ssaflag = 0; + + if (rq->half) halfflag = 1; + if (rq->full) fullflag = 1; + if (rq->gran) halfflag = 1; + if (rq->respaouter) halfflag = 1; + + if (rq->ghost) ghostflag = NS_GHOST; + if (rq->ssa) ssaflag = NS_SSA; + + int newtflag; + if (rq->newton == 0 && newton_pair) newtflag = 1; + else if (rq->newton == 0 && !newton_pair) newtflag = 0; + else if (rq->newton == 1) newtflag = 1; + else if (rq->newton == 2) newtflag = 0; + + // use flags to match exactly one of NStencil class masks, bit by bit + // exactly one of halfflag,fullflag is set and thus must match + + int mask; + + for (int i = 0; i < nsclass; i++) { + mask = stencilmasks[i]; + + if (halfflag) { + if (!(mask & NS_HALF)) continue; + } else if (fullflag) { + if (!(mask & NS_FULL)) continue; + } + + if (ghostflag != (mask & NS_GHOST)) continue; + if (ssaflag != (mask & NS_SSA)) continue; + + if (style == BIN && !(mask & NS_BIN)) continue; + if (style == MULTI && !(mask & NS_MULTI)) continue; + + + if (dimension == 2 && !(mask & NS_2D)) continue; + if (dimension == 3 && !(mask & NS_3D)) continue; + + if (newtflag && !(mask & NS_NEWTON)) continue; + if (!newtflag && !(mask & NS_NEWTOFF)) continue; + + if (!triclinic && !(mask & NS_ORTHO)) continue; + if (triclinic && !(mask & NS_TRI)) continue; + + return i+1; + } + + // error return if matched none + + return -1; +} + +/* ---------------------------------------------------------------------- + assign NPair class to a NeighList + use neigh request settings to build mask + match mask to list of masks of known NPair classes + return index+1 of match in list of masks + return 0 for no binning + return -1 if no match +------------------------------------------------------------------------- */ + +int Neighbor::choose_pair(NeighRequest *rq) +{ + // no NPair build performed + + if (rq->granhistory) return 0; + if (rq->respainner || rq->respamiddle) return 0; + + // error check for includegroup with ghost neighbor request + + if (includegroup && rq->ghost) + error->all(FLERR,"Neighbor include group not allowed " + "with ghost neighbors"); + + // flags for settings the request + system requires of NPair class + // copyflag = no/yes copy request + // skipflag = no/yes skip request + // halfflag = half request (gran and respa are also half lists) + // fullflag = full request + // halffullflag = half_from_full request + // sizeflag = no/yes gran request for finite-size particles + // ghostflag = no/yes ghost request + // respaflag = no/yes respa request + // off2onflag = no/yes off2on request + // onesideflag = no/yes granonesided request + // ssaflag = no/yes request + // ompflag = no/yes omp request + // intelflag = no/yes intel request + // kokkos_device_flag = no/yes Kokkos device request + // kokkos_host_flag = no/yes Kokkos host request + // newtflag = newton off/on request + // style = NSQ/BIN/MULTI neighbor style + // triclinic = orthgonal/triclinic box + + int copyflag,skipflag,halfflag,fullflag,halffullflag,sizeflag,respaflag, + ghostflag,off2onflag,onesideflag,ssaflag,ompflag,intelflag,kokkos_device_flag,kokkos_host_flag; + + copyflag = skipflag = halfflag = fullflag = halffullflag = sizeflag = + ghostflag = respaflag = off2onflag = onesideflag = ssaflag = + ompflag = intelflag = kokkos_device_flag = kokkos_host_flag = 0; + + if (rq->copy) copyflag = NP_COPY; + if (rq->skip) skipflag = NP_SKIP; + + // NOTE: exactly one of these request flags is set (see neigh_request.h) + // this requires gran/respaouter also set halfflag + // can simplify this logic, if follow NOTE in neigh_request.h + // all why do size/off2on and size/off2on/oneside set NP_HALF + // either should set both half & full, or half should be in file name + // to be consistent with how other NP classes use "half" + + if (rq->half) halfflag = 1; + if (rq->full) fullflag = 1; + if (rq->half_from_full) halffullflag = 1; + if (rq->gran) { + sizeflag = NP_SIZE; + halfflag = 1; + } + if (rq->respaouter) { + respaflag = NP_RESPA; + halfflag = 1; + } + + if (rq->ghost) ghostflag = NP_GHOST; + if (rq->off2on) off2onflag = NP_OFF2ON; + if (rq->granonesided) onesideflag = NP_ONESIDE; + if (rq->ssa) ssaflag = NP_SSA; + if (rq->omp) ompflag = NP_OMP; + if (rq->intel) intelflag = NP_INTEL; + if (rq->kokkos_device) kokkos_device_flag = NP_KOKKOS_DEVICE; + if (rq->kokkos_host) kokkos_host_flag = NP_KOKKOS_HOST; + + int newtflag; + if (rq->newton == 0 && newton_pair) newtflag = 1; + else if (rq->newton == 0 && !newton_pair) newtflag = 0; + else if (rq->newton == 1) newtflag = 1; + else if (rq->newton == 2) newtflag = 0; + + // use flags to match exactly one of NPair class masks, bit by bit + // copyflag match returns with no further checks + // exactly one of halfflag,fullflag,halffullflag is set and thus must match + + int mask; + + //printf("FLAGS: %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n", + // copyflag,skipflag,halfflag,fullflag,halffullflag, + // sizeflag,respaflag,ghostflag,off2onflag,onesideflag,ssaflag, + // ompflag,intelflag,newtflag); + + for (int i = 0; i < npclass; i++) { + mask = pairmasks[i]; + + if (copyflag && (mask & NP_COPY)) { + if (kokkos_device_flag != (mask & NP_KOKKOS_DEVICE)) continue; + if (kokkos_host_flag != (mask & NP_KOKKOS_HOST)) continue; + return i+1; + } + if (skipflag != (mask & NP_SKIP)) continue; + + if (halfflag) { + if (!(mask & NP_HALF)) continue; + } else if (fullflag) { + if (!(mask & NP_FULL)) continue; + } else if (halffullflag) { + if (!(mask & NP_HALFFULL)) continue; + } + + if (sizeflag != (mask & NP_SIZE)) continue; + if (respaflag != (mask & NP_RESPA)) continue; + if (ghostflag != (mask & NP_GHOST)) continue; + if (off2onflag != (mask & NP_OFF2ON)) continue; + if (onesideflag != (mask & NP_ONESIDE)) continue; + if (ssaflag != (mask & NP_SSA)) continue; + if (ompflag != (mask & NP_OMP)) continue; + if (intelflag != (mask & NP_INTEL)) continue; + if (kokkos_device_flag != (mask & NP_KOKKOS_DEVICE)) continue; + if (kokkos_host_flag != (mask & NP_KOKKOS_HOST)) continue; + + if (style == NSQ && !(mask & NP_NSQ)) continue; + if (style == BIN && !(mask & NP_BIN)) continue; + if (style == MULTI && !(mask & NP_MULTI)) continue; + + if (newtflag && !(mask & NP_NEWTON)) continue; + if (!newtflag && !(mask & NP_NEWTOFF)) continue; + + if (!triclinic && !(mask & NP_ORTHO)) continue; + if (triclinic && !(mask & NP_TRI)) continue; + + return i+1; + } + + //printf("NO MATCH\n"); + + // error return if matched none + + return -1; +} + +/* ---------------------------------------------------------------------- + called by other classes to request a pairwise neighbor list +------------------------------------------------------------------------- */ int Neighbor::request(void *requestor, int instance) { @@ -1016,6 +1506,7 @@ int Neighbor::request(void *requestor, int instance) } requests[nrequest] = new NeighRequest(lmp); + requests[nrequest]->index = nrequest; requests[nrequest]->requestor = requestor; requests[nrequest]->requestor_instance = instance; nrequest++; @@ -1023,450 +1514,59 @@ int Neighbor::request(void *requestor, int instance) } /* ---------------------------------------------------------------------- - determine which pair_build function each neigh list needs - based on settings of neigh request - copy -> copy_from function - skip -> granular function if gran, several options - respa function if respaouter, - skip_from function for everything else - ssa -> special case for USER-DPD pair styles - half_from_full, half, full, gran, respaouter -> - choose by newton and rq->newton and triclinic settings - style NSQ options = newton off, newton on - style BIN options = newton off, newton on and not tri, newton on and tri - stlye MULTI options = same options as BIN - if none of these, ptr = NULL since pair_build is not invoked for this list - use "else if" logic b/c skip,copy can be set in addition to half,full,etc + one instance per entry in style_neigh_bin.h ------------------------------------------------------------------------- */ -void Neighbor::choose_build(int index, NeighRequest *rq) +template +NBin *Neighbor::bin_creator(LAMMPS *lmp) { - PairPtr pb = NULL; - - if (rq->omp == 0 && rq->intel == 0) { - - if (rq->copy) pb = &Neighbor::copy_from; - - else if (rq->skip) { - if (rq->gran) { - NeighRequest *otherrq = requests[rq->otherlist]; - if (otherrq->newton == 0) { - pb = &Neighbor::skip_from_granular; - } else if (otherrq->newton == 1) { - error->all(FLERR,"Neighbor build method not supported"); - } else if (otherrq->newton == 2) { - if (rq->granonesided == 0) - pb = &Neighbor::skip_from_granular_off2on; - else if (rq->granonesided == 1) - pb = &Neighbor::skip_from_granular_off2on_onesided; - } - } - else if (rq->respaouter) pb = &Neighbor::skip_from_respa; - else pb = &Neighbor::skip_from; - - } else if (rq->ssa) { - if (rq->half_from_full) pb = &Neighbor::half_from_full_newton_ssa; - else pb = &Neighbor::half_bin_newton_ssa; - - } else if (rq->half_from_full) { - if (rq->newton == 0) { - if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton; - else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton; - } else if (rq->newton == 1) { - pb = &Neighbor::half_from_full_newton; - } else if (rq->newton == 2) { - pb = &Neighbor::half_from_full_no_newton; - } - - } else if (rq->half) { - if (style == NSQ) { - if (rq->newton == 0) { - if (newton_pair == 0) { - if (rq->ghost == 0) pb = &Neighbor::half_nsq_no_newton; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_nsq_no_newton_ghost; - } else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton; - } else if (rq->newton == 1) { - pb = &Neighbor::half_nsq_newton; - } else if (rq->newton == 2) { - if (rq->ghost == 0) pb = &Neighbor::half_nsq_no_newton; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_nsq_no_newton_ghost; - } - } else if (style == BIN) { - if (rq->newton == 0) { - if (newton_pair == 0) { - if (rq->ghost == 0) pb = &Neighbor::half_bin_no_newton; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_bin_no_newton_ghost; - } else if (triclinic == 0) { - pb = &Neighbor::half_bin_newton; - } else if (triclinic == 1) - pb = &Neighbor::half_bin_newton_tri; - } else if (rq->newton == 1) { - if (triclinic == 0) pb = &Neighbor::half_bin_newton; - else if (triclinic == 1) pb = &Neighbor::half_bin_newton_tri; - } else if (rq->newton == 2) { - if (rq->ghost == 0) pb = &Neighbor::half_bin_no_newton; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_bin_no_newton_ghost; - } - } else if (style == MULTI) { - if (rq->ghost == 1) - error->all(FLERR, - "Neighbor multi not yet enabled for ghost neighbors"); - if (rq->newton == 0) { - if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton; - else if (triclinic == 0) pb = &Neighbor::half_multi_newton; - else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri; - } else if (rq->newton == 1) { - if (triclinic == 0) pb = &Neighbor::half_multi_newton; - else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri; - } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton; - } - - } else if (rq->full) { - if (style == NSQ) { - if (rq->ghost == 0) pb = &Neighbor::full_nsq; - else if (includegroup) - error->all(FLERR, - "Neighbor include group not allowed with ghost neighbors"); - else pb = &Neighbor::full_nsq_ghost; - } else if (style == BIN) { - if (rq->ghost == 0) pb = &Neighbor::full_bin; - else if (includegroup) - error->all(FLERR, - "Neighbor include group not allowed with ghost neighbors"); - else pb = &Neighbor::full_bin_ghost; - } else if (style == MULTI) { - if (rq->ghost == 1) - error->all(FLERR, - "Neighbor multi not yet enabled for ghost neighbors"); - pb = &Neighbor::full_multi; - } - - } else if (rq->gran) { - if (rq->newton == 0) { - if (style == NSQ) { - if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton; - else if (newton_pair == 1) { - if (rq->granonesided == 0) pb = &Neighbor::granular_nsq_newton; - else pb = &Neighbor::granular_nsq_newton_onesided; - } - } else if (style == BIN) { - if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton; - else if (newton_pair == 1) { - if (triclinic == 0) { - if (rq->granonesided == 0) pb = &Neighbor::granular_bin_newton; - else pb = &Neighbor::granular_bin_newton_onesided; - } else if (triclinic == 1) { - if (rq->granonesided == 0) - pb = &Neighbor::granular_bin_newton_tri; - else error->all(FLERR,"Neighbor build method not supported"); - } - } - } else if (style == MULTI) - error->all(FLERR,"Neighbor multi not yet enabled for granular"); - } else if (rq->newton == 1) { - error->all(FLERR,"Neighbor build method not yet supported"); - } else if (rq->newton == 2) { - if (style == NSQ) pb = &Neighbor::granular_nsq_no_newton; - else if (style == BIN) { - if (triclinic == 0) pb = &Neighbor::granular_bin_no_newton; - else if (triclinic == 1) - error->all(FLERR,"Neighbor build method not yet supported"); - } else if (style == MULTI) - error->all(FLERR,"Neighbor multi not yet enabled for granular"); - } - - } else if (rq->respaouter) { - if (style == NSQ) { - if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton; - else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton; - } else if (style == BIN) { - if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton; - else if (triclinic == 0) pb = &Neighbor::respa_bin_newton; - else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri; - } else if (style == MULTI) - error->all(FLERR,"Neighbor multi not yet enabled for rRESPA"); - } - - // OMP versions of build methods - - } else { - - if (rq->copy) pb = &Neighbor::copy_from; - - else if (rq->skip) { - if (rq->gran && lists[index]->listgranhistory) - pb = &Neighbor::skip_from_granular; - else if (rq->respaouter) pb = &Neighbor::skip_from_respa; - else pb = &Neighbor::skip_from; - - } else if (rq->half_from_full) { - if (newton_pair == 0) pb = &Neighbor::half_from_full_no_newton_omp; - else if (newton_pair == 1) pb = &Neighbor::half_from_full_newton_omp; - - } else if (rq->half) { - if (style == NSQ) { - if (rq->newton == 0) { - if (newton_pair == 0) { - if (rq->ghost == 0) pb = &Neighbor::half_nsq_no_newton_omp; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_nsq_no_newton_ghost_omp; - } else if (newton_pair == 1) pb = &Neighbor::half_nsq_newton_omp; - } else if (rq->newton == 1) { - pb = &Neighbor::half_nsq_newton_omp; - } else if (rq->newton == 2) { - if (rq->ghost == 0) pb = &Neighbor::half_nsq_no_newton_omp; - else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_nsq_no_newton_ghost_omp; - } - } else if (style == BIN) { - if (rq->newton == 0) { - if (newton_pair == 0) { - if (rq->ghost == 0) { - if (rq->intel) pb = &Neighbor::half_bin_no_newton_intel; - else pb = &Neighbor::half_bin_no_newton_omp; - } else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_bin_no_newton_ghost_omp; - } else if (triclinic == 0) { - if (rq->intel) pb = &Neighbor::half_bin_newton_intel; - else pb = &Neighbor::half_bin_newton_omp; - } else if (triclinic == 1) { - if (rq->intel) pb = &Neighbor::half_bin_newton_tri_intel; - else pb = &Neighbor::half_bin_newton_tri_omp; - } - } else if (rq->newton == 1) { - if (triclinic == 0) { - if (rq->intel) pb = &Neighbor::half_bin_newton_intel; - else pb = &Neighbor::half_bin_newton_omp; - } else if (triclinic == 1) { - if (rq->intel) pb = &Neighbor::half_bin_newton_tri_intel; - else pb = &Neighbor::half_bin_newton_tri_omp; - } - } else if (rq->newton == 2) { - if (rq->ghost == 0) { - if (rq->intel) pb = &Neighbor::half_bin_no_newton_intel; - else pb = &Neighbor::half_bin_no_newton_omp; - } else if (includegroup) - error->all(FLERR,"Neighbor include group not allowed " - "with ghost neighbors"); - else pb = &Neighbor::half_bin_no_newton_ghost_omp; - } - } else if (style == MULTI) { - if (rq->ghost == 1) - error->all(FLERR, - "Neighbor multi not yet enabled for ghost neighbors"); - if (rq->newton == 0) { - if (newton_pair == 0) pb = &Neighbor::half_multi_no_newton_omp; - else if (triclinic == 0) pb = &Neighbor::half_multi_newton_omp; - else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri_omp; - } else if (rq->newton == 1) { - if (triclinic == 0) pb = &Neighbor::half_multi_newton_omp; - else if (triclinic == 1) pb = &Neighbor::half_multi_newton_tri_omp; - } else if (rq->newton == 2) pb = &Neighbor::half_multi_no_newton_omp; - } - - } else if (rq->full) { - if (style == NSQ) { - if (rq->ghost == 0) pb = &Neighbor::full_nsq_omp; - else if (includegroup) - error->all(FLERR, - "Neighbor include group not allowed with ghost neighbors"); - else pb = &Neighbor::full_nsq_ghost_omp; - } else if (style == BIN) { - if (rq->ghost == 0) { - if (rq->intel) pb = &Neighbor::full_bin_intel; - else pb = &Neighbor::full_bin_omp; - } else if (includegroup) - error->all(FLERR, - "Neighbor include group not allowed with ghost neighbors"); - else pb = &Neighbor::full_bin_ghost_omp; - } else if (style == MULTI) { - if (rq->ghost == 1) - error->all(FLERR, - "Neighbor multi not yet enabled for ghost neighbors"); - pb = &Neighbor::full_multi_omp; - } - - } else if (rq->gran) { - if (style == NSQ) { - if (newton_pair == 0) pb = &Neighbor::granular_nsq_no_newton_omp; - else if (newton_pair == 1) pb = &Neighbor::granular_nsq_newton_omp; - } else if (style == BIN) { - if (newton_pair == 0) pb = &Neighbor::granular_bin_no_newton_omp; - else if (triclinic == 0) pb = &Neighbor::granular_bin_newton_omp; - else if (triclinic == 1) pb = &Neighbor::granular_bin_newton_tri_omp; - } else if (style == MULTI) - error->all(FLERR,"Neighbor multi not yet enabled for granular"); - - } else if (rq->respaouter) { - if (style == NSQ) { - if (newton_pair == 0) pb = &Neighbor::respa_nsq_no_newton_omp; - else if (newton_pair == 1) pb = &Neighbor::respa_nsq_newton_omp; - } else if (style == BIN) { - if (newton_pair == 0) pb = &Neighbor::respa_bin_no_newton_omp; - else if (triclinic == 0) pb = &Neighbor::respa_bin_newton_omp; - else if (triclinic == 1) pb = &Neighbor::respa_bin_newton_tri_omp; - } else if (style == MULTI) - error->all(FLERR,"Neighbor multi not yet enabled for rRESPA"); - } - } - - pair_build[index] = pb; + return new T(lmp); } /* ---------------------------------------------------------------------- - determine which stencil_create function each neigh list needs - based on settings of neigh request, only called if style != NSQ - skip or copy or half_from_full -> no stencil - ssa = special case for USER-DPD pair styles - half, gran, respaouter, full -> choose by newton and tri and dimension - if none of these, ptr = NULL since this list needs no stencils - use "else if" b/c skip,copy can be set in addition to half,full,etc + one instance per entry in style_neigh_stencil.h ------------------------------------------------------------------------- */ -void Neighbor::choose_stencil(int index, NeighRequest *rq) +template +NStencil *Neighbor::stencil_creator(LAMMPS *lmp) { - StencilPtr sc = NULL; - - if (rq->skip || rq->copy || rq->half_from_full) sc = NULL; - - else if (rq->ssa) { - if (dimension == 2) sc = &Neighbor::stencil_half_bin_2d_ssa; - else if (dimension == 3) sc = &Neighbor::stencil_half_bin_3d_ssa; - - } else if (rq->half || rq->gran || rq->respaouter) { - if (style == BIN) { - if (rq->newton == 0) { - if (newton_pair == 0) { - if (dimension == 2) { - if (rq->ghost) sc = &Neighbor::stencil_half_ghost_bin_2d_no_newton; - else sc = &Neighbor::stencil_half_bin_2d_no_newton; - } else if (dimension == 3) { - if (rq->ghost) sc = &Neighbor::stencil_half_ghost_bin_3d_no_newton; - else sc = &Neighbor::stencil_half_bin_3d_no_newton; - } - } else if (triclinic == 0) { - if (dimension == 2) - sc = &Neighbor::stencil_half_bin_2d_newton; - else if (dimension == 3) - sc = &Neighbor::stencil_half_bin_3d_newton; - } else if (triclinic == 1) { - if (dimension == 2) - sc = &Neighbor::stencil_half_bin_2d_newton_tri; - else if (dimension == 3) - sc = &Neighbor::stencil_half_bin_3d_newton_tri; - } - } else if (rq->newton == 1) { - if (triclinic == 0) { - if (dimension == 2) - sc = &Neighbor::stencil_half_bin_2d_newton; - else if (dimension == 3) - sc = &Neighbor::stencil_half_bin_3d_newton; - } else if (triclinic == 1) { - if (dimension == 2) - sc = &Neighbor::stencil_half_bin_2d_newton_tri; - else if (dimension == 3) - sc = &Neighbor::stencil_half_bin_3d_newton_tri; - } - } else if (rq->newton == 2) { - if (dimension == 2) - if (rq->ghost) sc = &Neighbor::stencil_half_ghost_bin_2d_no_newton; - else sc = &Neighbor::stencil_half_bin_2d_no_newton; - else if (dimension == 3) { - if (rq->ghost) sc = &Neighbor::stencil_half_ghost_bin_3d_no_newton; - else sc = &Neighbor::stencil_half_bin_3d_no_newton; - } - } - - } else if (style == MULTI) { - if (rq->newton == 0) { - if (newton_pair == 0) { - if (dimension == 2) - sc = &Neighbor::stencil_half_multi_2d_no_newton; - else if (dimension == 3) - sc = &Neighbor::stencil_half_multi_3d_no_newton; - } else if (triclinic == 0) { - if (dimension == 2) - sc = &Neighbor::stencil_half_multi_2d_newton; - else if (dimension == 3) - sc = &Neighbor::stencil_half_multi_3d_newton; - } else if (triclinic == 1) { - if (dimension == 2) - sc = &Neighbor::stencil_half_multi_2d_newton_tri; - else if (dimension == 3) - sc = &Neighbor::stencil_half_multi_3d_newton_tri; - } - } else if (rq->newton == 1) { - if (triclinic == 0) { - if (dimension == 2) - sc = &Neighbor::stencil_half_multi_2d_newton; - else if (dimension == 3) - sc = &Neighbor::stencil_half_multi_3d_newton; - } else if (triclinic == 1) { - if (dimension == 2) - sc = &Neighbor::stencil_half_multi_2d_newton_tri; - else if (dimension == 3) - sc = &Neighbor::stencil_half_multi_3d_newton_tri; - } - } else if (rq->newton == 2) { - if (dimension == 2) - sc = &Neighbor::stencil_half_multi_2d_no_newton; - else if (dimension == 3) - sc = &Neighbor::stencil_half_multi_3d_no_newton; - } - } - - } else if (rq->full) { - if (style == BIN) { - if (dimension == 2) { - if (rq->ghost) sc = &Neighbor::stencil_full_ghost_bin_2d; - else sc = &Neighbor::stencil_full_bin_2d; - } - else if (dimension == 3) { - if (rq->ghost) sc = &Neighbor::stencil_full_ghost_bin_3d; - else sc = &Neighbor::stencil_full_bin_3d; - } - } else if (style == MULTI) { - if (dimension == 2) sc = &Neighbor::stencil_full_multi_2d; - else if (dimension == 3) sc = &Neighbor::stencil_full_multi_3d; - } - } - - stencil_create[index] = sc; + return new T(lmp); } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + one instance per entry in style_neigh_pair.h +------------------------------------------------------------------------- */ -void Neighbor::print_lists_of_lists() +template +NPair *Neighbor::pair_creator(LAMMPS *lmp) { - if (comm->me == 0) { - printf("Build lists = %d: ",nblist); - for (int i = 0; i < nblist; i++) printf("%d ",blist[i]); - printf("\n"); - printf("Grow lists = %d: ",nglist); - for (int i = 0; i < nglist; i++) printf("%d ",glist[i]); - printf("\n"); - printf("Stencil lists = %d: ",nslist); - for (int i = 0; i < nslist; i++) printf("%d ",slist[i]); - printf("\n"); + return new T(lmp); +} + +/* ---------------------------------------------------------------------- + setup neighbor binning and neighbor stencils + called before run and every reneighbor if box size/shape changes + only operates on perpetual lists + build_one() operates on occasional lists +------------------------------------------------------------------------- */ + +void Neighbor::setup_bins() +{ + // invoke setup_bins() for all NBin + // actual binning is performed in build() + + for (int i = 0; i < nbin; i++) + neigh_bin[i]->setup_bins(style); + + // invoke create_setup() and create() for all perpetual NStencil + // same ops performed for occasional lists in build_one() + + for (int i = 0; i < nstencil_perpetual; i++) { + neigh_stencil[slist[i]]->create_setup(); + neigh_stencil[slist[i]]->create(); } + + last_setup_bins = update->ntimestep; } /* ---------------------------------------------------------------------- */ @@ -1554,22 +1654,29 @@ int Neighbor::check_distance() /* ---------------------------------------------------------------------- build perpetual neighbor lists called at setup and every few timesteps during run or minimization - topology lists also built if topoflag = 1, USER-CUDA calls with topoflag = 0 + topology lists also built if topoflag = 1 (Kokkos calls with topoflag=0) ------------------------------------------------------------------------- */ void Neighbor::build(int topoflag) { - int i; + int i,m; ago = 0; ncalls++; lastcall = update->ntimestep; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + // check that using special bond flags will not overflow neigh lists + + if (nall > NEIGHMASK) + error->one(FLERR,"Too many local+ghost atoms for neighbor list"); + // store current atom positions and box size if needed if (dist_check) { double **x = atom->x; - int nlocal = atom->nlocal; if (includegroup) nlocal = atom->nfirst; if (atom->nmax > maxhold) { maxhold = atom->nmax; @@ -1601,53 +1708,61 @@ void Neighbor::build(int topoflag) } } - // if any lists store neighbors of ghosts: - // invoke grow() if nlocal+nghost exceeds previous list size - // else only invoke grow() if nlocal exceeds previous list size - // only for lists with growflag set and which are perpetual (glist) + // bin atoms for all NBin instances + // not just NBin associated with perpetual lists + // b/c cannot wait to bin occasional lists in build_one() call + // if bin then, atoms may have moved outside of proc domain & bin extent, + // leading to errors or even a crash - if (anyghostlist && atom->nmax > maxatom) { - maxatom = atom->nmax; - for (i = 0; i < nglist; i++) lists[glist[i]]->grow(maxatom); - } else if (atom->nmax > maxatom) { - maxatom = atom->nmax; - for (i = 0; i < nglist; i++) lists[glist[i]]->grow(maxatom); + if (style != NSQ) { + for (int i = 0; i < nbin; i++) { + neigh_bin[i]->bin_atoms_setup(nall); + neigh_bin[i]->bin_atoms(); + } } - // extend atom bin list if necessary + // build pairwise lists for all perpetual NPair/NeighList + // grow() with nlocal/nall args so that only realloc if have to - if (style != NSQ && atom->nmax > maxbin) { - maxbin = atom->nmax; - memory->destroy(bins); - memory->create(bins,maxbin,"bins"); + for (i = 0; i < npair_perpetual; i++) { + m = plist[i]; + lists[m]->grow(nlocal,nall); + neigh_pair[m]->build_setup(); + neigh_pair[m]->build(lists[m]); } - // check that using special bond flags will not overflow neigh lists - - if (atom->nlocal+atom->nghost > NEIGHMASK) - error->one(FLERR,"Too many local+ghost atoms for neighbor list"); - - // invoke building of pair and molecular topology neighbor lists - // only for pairwise lists with buildflag set - // blist is for standard neigh lists, otherwise is a Kokkos list - - for (i = 0; i < nblist; i++) - (this->*pair_build[blist[i]])(lists[blist[i]]); + // build topology lists for bonds/angles/etc if (atom->molecular && topoflag) build_topology(); } /* ---------------------------------------------------------------------- - build all topology neighbor lists every few timesteps - normally built with pair lists, but USER-CUDA separates them + build topology neighbor lists: bond, angle, dihedral, improper + copy their list info back to Neighbor for access by bond/angle/etc classes ------------------------------------------------------------------------- */ void Neighbor::build_topology() { - if (force->bond) (this->*bond_build)(); - if (force->angle) (this->*angle_build)(); - if (force->dihedral) (this->*dihedral_build)(); - if (force->improper) (this->*improper_build)(); + if (force->bond) { + neigh_bond->build(); + nbondlist = neigh_bond->nbondlist; + bondlist = neigh_bond->bondlist; + } + if (force->angle) { + neigh_angle->build(); + nanglelist = neigh_angle->nanglelist; + anglelist = neigh_angle->anglelist; + } + if (force->dihedral) { + neigh_dihedral->build(); + ndihedrallist = neigh_dihedral->ndihedrallist; + dihedrallist = neigh_dihedral->dihedrallist; + } + if (force->improper) { + neigh_improper->build(); + nimproperlist = neigh_improper->nimproperlist; + improperlist = neigh_improper->improperlist; + } } /* ---------------------------------------------------------------------- @@ -1663,254 +1778,45 @@ void Neighbor::build_one(class NeighList *mylist, int preflag) error->all(FLERR,"Trying to build an occasional neighbor list " "before initialization completed"); + // build_one() should never be invoked on a perpetual list + + if (!mylist->occasional) + error->all(FLERR,"Neighbor build one invoked on perpetual list"); + // no need to build if already built since last re-neighbor // preflag is set by fix bond/create and fix bond/swap // b/c they invoke build_one() on same step neigh list is re-built, // but before re-build, so need to use ">" instead of ">=" + NPair *np = neigh_pair[mylist->index]; + if (preflag) { - if (mylist->last_build > lastcall) return; + if (np->last_build > lastcall) return; } else { - if (mylist->last_build >= lastcall) return; + if (np->last_build >= lastcall) return; } - mylist->last_build = update->ntimestep; + // if this is copy list and parent is occasional list, + // or this is half_from_full and parent is occasional list, + // insure parent is current - // update stencils and grow atom arrays as needed - // only for relevant settings of stencilflag and growflag - // grow atom array for this list to current size of perpetual lists + if (mylist->listcopy && mylist->listcopy->occasional) + build_one(mylist->listcopy,preflag); + if (mylist->listfull && mylist->listfull->occasional) + build_one(mylist->listfull,preflag); - if (mylist->stencilflag) { - mylist->stencil_allocate(smax,style); - (this->*stencil_create[mylist->index])(mylist,sx,sy,sz); + // create stencil if hasn't been created since last setup_bins() call + + NStencil *ns = np->ns; + if (ns && ns->last_create < last_setup_bins) { + ns->create_setup(); + ns->create(); } - if (mylist->growflag) mylist->grow(maxatom); + // build the list - // build list I, turning off atom binning - // binning results from last re-neighbor should be used instead - // if re-bin now, atoms may have moved outside of proc domain & bin extent, - // leading to errors or even a crash - - binatomflag = 0; - (this->*pair_build[mylist->index])(mylist); - binatomflag = 1; -} - -/* ---------------------------------------------------------------------- - setup neighbor binning parameters - bin numbering in each dimension is global: - 0 = 0.0 to binsize, 1 = binsize to 2*binsize, etc - nbin-1,nbin,etc = bbox-binsize to bbox, bbox to bbox+binsize, etc - -1,-2,etc = -binsize to 0.0, -2*binsize to -binsize, etc - code will work for any binsize - since next(xyz) and stencil extend as far as necessary - binsize = 1/2 of cutoff is roughly optimal - for orthogonal boxes: - a dim must be filled exactly by integer # of bins - in periodic, procs on both sides of PBC must see same bin boundary - in non-periodic, coord2bin() still assumes this by use of nbin xyz - for triclinic boxes: - tilted simulation box cannot contain integer # of bins - stencil & neigh list built differently to account for this - mbinlo = lowest global bin any of my ghost atoms could fall into - mbinhi = highest global bin any of my ghost atoms could fall into - mbin = number of bins I need in a dimension -------------------------------------------------------------------------- */ - -void Neighbor::setup_bins() -{ - // bbox = size of bbox of entire domain - // bsubbox lo/hi = bounding box of my subdomain extended by comm->cutghost - // for triclinic: - // bbox bounds all 8 corners of tilted box - // subdomain is in lamda coords - // include dimension-dependent extension via comm->cutghost - // domain->bbox() converts lamda extent to box coords and computes bbox - - double bbox[3],bsubboxlo[3],bsubboxhi[3]; - double *cutghost = comm->cutghost; - - if (triclinic == 0) { - bsubboxlo[0] = domain->sublo[0] - cutghost[0]; - bsubboxlo[1] = domain->sublo[1] - cutghost[1]; - bsubboxlo[2] = domain->sublo[2] - cutghost[2]; - bsubboxhi[0] = domain->subhi[0] + cutghost[0]; - bsubboxhi[1] = domain->subhi[1] + cutghost[1]; - bsubboxhi[2] = domain->subhi[2] + cutghost[2]; - } else { - double lo[3],hi[3]; - lo[0] = domain->sublo_lamda[0] - cutghost[0]; - lo[1] = domain->sublo_lamda[1] - cutghost[1]; - lo[2] = domain->sublo_lamda[2] - cutghost[2]; - hi[0] = domain->subhi_lamda[0] + cutghost[0]; - hi[1] = domain->subhi_lamda[1] + cutghost[1]; - hi[2] = domain->subhi_lamda[2] + cutghost[2]; - domain->bbox(lo,hi,bsubboxlo,bsubboxhi); - } - - bbox[0] = bboxhi[0] - bboxlo[0]; - bbox[1] = bboxhi[1] - bboxlo[1]; - bbox[2] = bboxhi[2] - bboxlo[2]; - - // optimal bin size is roughly 1/2 the cutoff - // for BIN style, binsize = 1/2 of max neighbor cutoff - // for MULTI style, binsize = 1/2 of min neighbor cutoff - // special case of all cutoffs = 0.0, binsize = box size - - double binsize_optimal; - if (binsizeflag) binsize_optimal = binsize_user; - else if (style == BIN) binsize_optimal = 0.5*cutneighmax; - else binsize_optimal = 0.5*cutneighmin; - if (binsize_optimal == 0.0) binsize_optimal = bbox[0]; - double binsizeinv = 1.0/binsize_optimal; - - // test for too many global bins in any dimension due to huge global domain - - if (bbox[0]*binsizeinv > MAXSMALLINT || bbox[1]*binsizeinv > MAXSMALLINT || - bbox[2]*binsizeinv > MAXSMALLINT) - error->all(FLERR,"Domain too large for neighbor bins"); - - // create actual bins - // always have one bin even if cutoff > bbox - // for 2d, nbinz = 1 - - nbinx = static_cast (bbox[0]*binsizeinv); - nbiny = static_cast (bbox[1]*binsizeinv); - if (dimension == 3) nbinz = static_cast (bbox[2]*binsizeinv); - else nbinz = 1; - - if (nbinx == 0) nbinx = 1; - if (nbiny == 0) nbiny = 1; - if (nbinz == 0) nbinz = 1; - - // compute actual bin size for nbins to fit into box exactly - // error if actual bin size << cutoff, since will create a zillion bins - // this happens when nbin = 1 and box size << cutoff - // typically due to non-periodic, flat system in a particular dim - // in that extreme case, should use NSQ not BIN neighbor style - - binsizex = bbox[0]/nbinx; - binsizey = bbox[1]/nbiny; - binsizez = bbox[2]/nbinz; - - bininvx = 1.0 / binsizex; - bininvy = 1.0 / binsizey; - bininvz = 1.0 / binsizez; - - if (binsize_optimal*bininvx > CUT2BIN_RATIO || - binsize_optimal*bininvy > CUT2BIN_RATIO || - binsize_optimal*bininvz > CUT2BIN_RATIO) - error->all(FLERR,"Cannot use neighbor bins - box size << cutoff"); - - // mbinlo/hi = lowest and highest global bins my ghost atoms could be in - // coord = lowest and highest values of coords for my ghost atoms - // static_cast(-1.5) = -1, so subract additional -1 - // add in SMALL for round-off safety - - int mbinxhi,mbinyhi,mbinzhi; - double coord; - - coord = bsubboxlo[0] - SMALL*bbox[0]; - mbinxlo = static_cast ((coord-bboxlo[0])*bininvx); - if (coord < bboxlo[0]) mbinxlo = mbinxlo - 1; - coord = bsubboxhi[0] + SMALL*bbox[0]; - mbinxhi = static_cast ((coord-bboxlo[0])*bininvx); - - coord = bsubboxlo[1] - SMALL*bbox[1]; - mbinylo = static_cast ((coord-bboxlo[1])*bininvy); - if (coord < bboxlo[1]) mbinylo = mbinylo - 1; - coord = bsubboxhi[1] + SMALL*bbox[1]; - mbinyhi = static_cast ((coord-bboxlo[1])*bininvy); - - if (dimension == 3) { - coord = bsubboxlo[2] - SMALL*bbox[2]; - mbinzlo = static_cast ((coord-bboxlo[2])*bininvz); - if (coord < bboxlo[2]) mbinzlo = mbinzlo - 1; - coord = bsubboxhi[2] + SMALL*bbox[2]; - mbinzhi = static_cast ((coord-bboxlo[2])*bininvz); - } - - // extend bins by 1 to insure stencil extent is included - // if 2d, only 1 bin in z - - mbinxlo = mbinxlo - 1; - mbinxhi = mbinxhi + 1; - mbinx = mbinxhi - mbinxlo + 1; - - mbinylo = mbinylo - 1; - mbinyhi = mbinyhi + 1; - mbiny = mbinyhi - mbinylo + 1; - - if (dimension == 3) { - mbinzlo = mbinzlo - 1; - mbinzhi = mbinzhi + 1; - } else mbinzlo = mbinzhi = 0; - mbinz = mbinzhi - mbinzlo + 1; - - // memory for bin ptrs - - bigint bbin = ((bigint) mbinx) * ((bigint) mbiny) * ((bigint) mbinz); - if (bbin > MAXSMALLINT) error->one(FLERR,"Too many neighbor bins"); - mbins = bbin; - if (mbins > maxhead) { - maxhead = mbins; - memory->destroy(binhead); - - // USER-INTEL package requires one additional element - #if defined(LMP_USER_INTEL) - memory->create(binhead,maxhead + 1,"neigh:binhead"); - #else - memory->create(binhead,maxhead,"neigh:binhead"); - #endif - } - - // create stencil of bins to search over in neighbor list construction - // sx,sy,sz = max range of stencil in each dim - // smax = max possible size of entire 3d stencil - // stencil is empty if cutneighmax = 0.0 - - sx = static_cast (cutneighmax*bininvx); - if (sx*binsizex < cutneighmax) sx++; - sy = static_cast (cutneighmax*bininvy); - if (sy*binsizey < cutneighmax) sy++; - sz = static_cast (cutneighmax*bininvz); - if (sz*binsizez < cutneighmax) sz++; - if (dimension == 2) sz = 0; - smax = (2*sx+1) * (2*sy+1) * (2*sz+1); - - // create stencils for pairwise neighbor lists - // only done for lists with stencilflag and buildflag set - - for (int i = 0; i < nslist; i++) { - if (lists[slist[i]]) { - lists[slist[i]]->stencil_allocate(smax,style); - (this->*stencil_create[slist[i]])(lists[slist[i]],sx,sy,sz); - } else setup_bins_kokkos(i); - } -} - -/* ---------------------------------------------------------------------- - compute closest distance between central bin (0,0,0) and bin (i,j,k) -------------------------------------------------------------------------- */ - -double Neighbor::bin_distance(int i, int j, int k) -{ - double delx,dely,delz; - - if (i > 0) delx = (i-1)*binsizex; - else if (i == 0) delx = 0.0; - else delx = (i+1)*binsizex; - - if (j > 0) dely = (j-1)*binsizey; - else if (j == 0) dely = 0.0; - else dely = (j+1)*binsizey; - - if (k > 0) delz = (k-1)*binsizez; - else if (k == 0) delz = 0.0; - else delz = (k+1)*binsizez; - - return (delx*delx + dely*dely + delz*delz); + np->build_setup(); + np->build(mylist); } /* ---------------------------------------------------------------------- @@ -1933,14 +1839,31 @@ void Neighbor::set(int narg, char **arg) } /* ---------------------------------------------------------------------- - reset timestamps in all NeighList classes + reset timestamps in all NeignBin, NStencil, NPair classes so that neighbor lists will rebuild properly with timestep change ------------------------------------------------------------------------- */ void Neighbor::reset_timestep(bigint ntimestep) { - for (int i = 0; i < nlist; i++) - lists[i]->last_build = -1; + for (int i = 0; i < nbin; i++) { + neigh_bin[i]->last_setup = -1; + neigh_bin[i]->last_bin = -1; + neigh_bin[i]->last_bin_memory = -1; + } + + for (int i = 0; i < nstencil; i++) { + neigh_stencil[i]->last_create = -1; + neigh_stencil[i]->last_stencil_memory = -1; + neigh_stencil[i]->last_copy_bin = -1; + } + + for (int i = 0; i < nlist; i++) { + if (!neigh_pair[i]) continue; + neigh_pair[i]->last_build = -1; + neigh_pair[i]->last_copy_bin_setup = -1; + neigh_pair[i]->last_copy_bin = -1; + neigh_pair[i]->last_copy_stencil = -1; + } } /* ---------------------------------------------------------------------- @@ -2061,161 +1984,6 @@ void Neighbor::modify_params(int narg, char **arg) } } -/* ---------------------------------------------------------------------- - bin owned and ghost atoms -------------------------------------------------------------------------- */ - -void Neighbor::bin_atoms() -{ - int i,ibin; - - for (i = 0; i < mbins; i++) binhead[i] = -1; - - // bin in reverse order so linked list will be in forward order - // also puts ghost atoms at end of list, which is necessary - - double **x = atom->x; - int *mask = atom->mask; - int nlocal = atom->nlocal; - int nall = nlocal + atom->nghost; - - if (includegroup) { - int bitmask = group->bitmask[includegroup]; - for (i = nall-1; i >= nlocal; i--) { - if (mask[i] & bitmask) { - ibin = coord2bin(x[i]); - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - } - for (i = atom->nfirst-1; i >= 0; i--) { - ibin = coord2bin(x[i]); - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - - } else { - for (i = nall-1; i >= 0; i--) { - ibin = coord2bin(x[i]); - bins[i] = binhead[ibin]; - binhead[ibin] = i; - } - } -} - -/* ---------------------------------------------------------------------- - convert atom coords into local bin # - for orthogonal, only ghost atoms will have coord >= bboxhi or coord < bboxlo - take special care to insure ghosts are in correct bins even w/ roundoff - hi ghost atoms = nbin,nbin+1,etc - owned atoms = 0 to nbin-1 - lo ghost atoms = -1,-2,etc - this is necessary so that both procs on either side of PBC - treat a pair of atoms straddling the PBC in a consistent way - for triclinic, doesn't matter since stencil & neigh list built differently -------------------------------------------------------------------------- */ - -int Neighbor::coord2bin(double *x) -{ - int ix,iy,iz; - - if (!ISFINITE(x[0]) || !ISFINITE(x[1]) || !ISFINITE(x[2])) - error->one(FLERR,"Non-numeric positions - simulation unstable"); - - if (x[0] >= bboxhi[0]) - ix = static_cast ((x[0]-bboxhi[0])*bininvx) + nbinx; - else if (x[0] >= bboxlo[0]) { - ix = static_cast ((x[0]-bboxlo[0])*bininvx); - ix = MIN(ix,nbinx-1); - } else - ix = static_cast ((x[0]-bboxlo[0])*bininvx) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast ((x[1]-bboxhi[1])*bininvy) + nbiny; - else if (x[1] >= bboxlo[1]) { - iy = static_cast ((x[1]-bboxlo[1])*bininvy); - iy = MIN(iy,nbiny-1); - } else - iy = static_cast ((x[1]-bboxlo[1])*bininvy) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast ((x[2]-bboxhi[2])*bininvz) + nbinz; - else if (x[2] >= bboxlo[2]) { - iz = static_cast ((x[2]-bboxlo[2])*bininvz); - iz = MIN(iz,nbinz-1); - } else - iz = static_cast ((x[2]-bboxlo[2])*bininvz) - 1; - - return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); -} - -/* ---------------------------------------------------------------------- - same as coord2bin, but also return ix,iy,iz offsets in each dim -------------------------------------------------------------------------- */ - -int Neighbor::coord2bin(double *x, int &ix, int &iy, int &iz) -{ - if (!ISFINITE(x[0]) || !ISFINITE(x[1]) || !ISFINITE(x[2])) - error->one(FLERR,"Non-numeric positions - simulation unstable"); - - if (x[0] >= bboxhi[0]) - ix = static_cast ((x[0]-bboxhi[0])*bininvx) + nbinx; - else if (x[0] >= bboxlo[0]) { - ix = static_cast ((x[0]-bboxlo[0])*bininvx); - ix = MIN(ix,nbinx-1); - } else - ix = static_cast ((x[0]-bboxlo[0])*bininvx) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast ((x[1]-bboxhi[1])*bininvy) + nbiny; - else if (x[1] >= bboxlo[1]) { - iy = static_cast ((x[1]-bboxlo[1])*bininvy); - iy = MIN(iy,nbiny-1); - } else - iy = static_cast ((x[1]-bboxlo[1])*bininvy) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast ((x[2]-bboxhi[2])*bininvz) + nbinz; - else if (x[2] >= bboxlo[2]) { - iz = static_cast ((x[2]-bboxlo[2])*bininvz); - iz = MIN(iz,nbinz-1); - } else - iz = static_cast ((x[2]-bboxlo[2])*bininvz) - 1; - - ix -= mbinxlo; - iy -= mbinylo; - iz -= mbinzlo; - return iz*mbiny*mbinx + iy*mbinx + ix; -} - -/* ---------------------------------------------------------------------- - test if atom pair i,j is excluded from neighbor list - due to type, group, molecule settings from neigh_modify command - return 1 if should be excluded, 0 if included -------------------------------------------------------------------------- */ - -int Neighbor::exclusion(int i, int j, int itype, int jtype, - int *mask, tagint *molecule) const { - int m; - - if (nex_type && ex_type[itype][jtype]) return 1; - - if (nex_group) { - for (m = 0; m < nex_group; m++) { - if (mask[i] & ex1_bit[m] && mask[j] & ex2_bit[m]) return 1; - if (mask[i] & ex2_bit[m] && mask[j] & ex1_bit[m]) return 1; - } - } - - if (nex_mol) { - for (m = 0; m < nex_mol; m++) - if (mask[i] & ex_mol_bit[m] && mask[j] & ex_mol_bit[m] && - molecule[i] == molecule[j]) return 1; - } - - return 0; -} - /* ---------------------------------------------------------------------- remove the first group-group exclusion matching group1, group2 ------------------------------------------------------------------------- */ @@ -2240,30 +2008,6 @@ void Neighbor::exclusion_group_group_delete(int group1, int group2) nex_group--; } -/* ---------------------------------------------------------------------- - return # of bytes of allocated memory -------------------------------------------------------------------------- */ - -bigint Neighbor::memory_usage() -{ - bigint bytes = 0; - bytes += memory->usage(xhold,maxhold,3); - - if (style != NSQ) { - bytes += memory->usage(bins,maxbin); - bytes += memory->usage(binhead,maxhead); - } - - for (int i = 0; i < nrequest; i++) - if (lists[i]) bytes += lists[i]->memory_usage(); - - bytes += memory->usage(bondlist,maxbond,3); - bytes += memory->usage(anglelist,maxangle,4); - bytes += memory->usage(dihedrallist,maxdihedral,5); - bytes += memory->usage(improperlist,maximproper,5); - - return bytes; -} /* ---------------------------------------------------------------------- return the value of exclude - used to check compatibility with GPU @@ -2273,3 +2017,27 @@ int Neighbor::exclude_setting() { return exclude; } + +/* ---------------------------------------------------------------------- + return # of bytes of allocated memory +------------------------------------------------------------------------- */ + +bigint Neighbor::memory_usage() +{ + bigint bytes = 0; + bytes += memory->usage(xhold,maxhold,3); + + for (int i = 0; i < nlist; i++) + if (lists[i]) bytes += lists[i]->memory_usage(); + for (int i = 0; i < nstencil; i++) + bytes += neigh_stencil[i]->memory_usage(); + for (int i = 0; i < nbin; i++) + bytes += neigh_bin[i]->memory_usage(); + + if (neigh_bond) bytes += neigh_bond->memory_usage(); + if (neigh_angle) bytes += neigh_angle->memory_usage(); + if (neigh_dihedral) bytes += neigh_dihedral->memory_usage(); + if (neigh_improper) bytes += neigh_improper->memory_usage(); + + return bytes; +} diff --git a/src/neighbor.h b/src/neighbor.h index 23fd663e2b..eb603ad84f 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -15,12 +15,11 @@ #define LMP_NEIGHBOR_H #include "pointers.h" +#include namespace LAMMPS_NS { class Neighbor : protected Pointers { - friend class Cuda; - public: int style; // 0,1,2 = nsq, bin, multi int every; // build every this many steps @@ -31,12 +30,18 @@ class Neighbor : protected Pointers { int oneatom; // max # of neighbors for one atom int includegroup; // only build pairwise lists for this group int build_once; // 1 if only build lists once per run - int cudable; // GPU <-> CPU communication flag for CUDA double skin; // skin distance double cutneighmin; // min neighbor cutoff for all type pairs double cutneighmax; // max neighbor cutoff for all type pairs + double cutneighmaxsq; // cutneighmax squared + double **cutneighsq; // neighbor cutneigh sq for each type pair + double **cutneighghostsq; // cutneigh sq for each ghost type pair double *cuttype; // for each type, max neigh cut w/ others + double *cuttypesq; // cuttype squared + double cut_inner_sq; // outer cutoff for inner neighbor list + double cut_middle_sq; // outer cutoff for middle neighbor list + double cut_middle_inside_sq; // inner cutoff for middle neighbor list int binsizeflag; // user-chosen bin size double binsize_user; // set externally by some accelerator pkgs @@ -45,20 +50,47 @@ class Neighbor : protected Pointers { bigint ndanger; // # of dangerous builds bigint lastcall; // timestep of last neighbor::build() call - int nrequest; // requests for pairwise neighbor lists - class NeighRequest **requests; // from Pair, Fix, Compute, Command classes - int maxrequest; + // geometry and static info, used by other Neigh classes - int old_style,old_nrequest; // previous run info to avoid - int old_triclinic,old_pgsize; // re-creation of pairwise neighbor lists - int old_oneatom,old_every; - int old_delay,old_check; - double old_cutoff; + double *bboxlo,*bboxhi; // ptrs to full domain bounding box + // different for orthog vs triclinic + double *zeroes; // vector of zeroes for shear history init - class NeighRequest **old_requests; + // exclusion info, used by NeighPair + + int exclude; // 0 if no type/group exclusions, 1 if yes + + int nex_type; // # of entries in type exclusion list + int *ex1_type,*ex2_type; // pairs of types to exclude + int **ex_type; // 2d array of excluded type pairs + + int nex_group; // # of entries in group exclusion list + int *ex1_group,*ex2_group; // pairs of group #'s to exclude + int *ex1_bit,*ex2_bit; // pairs of group bits to exclude + + int nex_mol; // # of entries in molecule exclusion list + int *ex_mol_group; // molecule group #'s to exclude + int *ex_mol_bit; // molecule group bits to exclude + + // special info, used by NeighPair + + int special_flag[4]; // flags for 1-2, 1-3, 1-4 neighbors + + // cluster setting, used by NeighTopo + + int cluster_check; // 1 if check bond/angle/etc satisfies minimg + + // pairwise neighbor lists and corresponding requests + + int nlist; // # of pairwise neighbor lists + int nrequest; // # of requests, same as nlist + int old_nrequest; // RQ count for run that just finished - int nlist; // pairwise neighbor lists class NeighList **lists; + class NeighRequest **requests; // from Pair,Fix,Compute,Command classes + class NeighRequest **old_requests; // accessed by Finish + + // data from topology neighbor lists int nbondlist; // list of bonds to compute int **bondlist; @@ -69,295 +101,174 @@ class Neighbor : protected Pointers { int nimproperlist; // list of impropers to compute int **improperlist; - int cluster_check; // 1 if check bond/angle/etc satisfies minimg - - // methods + // public methods Neighbor(class LAMMPS *); virtual ~Neighbor(); virtual void init(); - int request(void *, int instance=0); // another class requests a neigh list - void print_lists_of_lists(); // debug print out + int request(void *, int instance=0); int decide(); // decide whether to build or not virtual int check_distance(); // check max distance moved since last build void setup_bins(); // setup bins based on box and cutoff - virtual void build(int topoflag=1); // create all neighbor lists (pair,bond) - virtual void build_topology(); // create all topology neighbor lists - void build_one(class NeighList *list, - int preflag=0); // create a single one-time neigh list + virtual void build(int topoflag=1); // build all perpetual neighbor lists + virtual void build_topology(); // pairwise topology neighbor lists + void build_one(class NeighList *list, int preflag=0); + // create a one-time pairwise neigh list void set(int, char **); // set neighbor style and skin distance void reset_timestep(bigint); // reset of timestep counter - void modify_params(int, char**); // modify parameters that control builds - bigint memory_usage(); - int exclude_setting(); + void modify_params(int, char**); // modify params that control builds + void exclusion_group_group_delete(int, int); // rm a group-group exclusion + int exclude_setting(); // return exclude value to accelerator pkg + + bigint memory_usage(); protected: int me,nprocs; + int firsttime; // flag for calling init_styles() only once - int maxatom; // size of atom-based NeighList arrays - int maxbond,maxangle,maxdihedral,maximproper; // size of bond lists - int maxwt; // max weighting factor applied + 1 + int dimension; // 2/3 for 2d/3d + int triclinic; // 0 if domain is orthog, 1 if triclinic + int newton_pair; // 0 if newton off for pairwise, 1 if on int must_check; // 1 if must check other classes to reneigh int restart_check; // 1 if restart enabled, 0 if no int fix_check; // # of fixes that induce reneigh int *fixchecklist; // which fixes to check - double **cutneighsq; // neighbor cutneigh sq for each type pair - double **cutneighghostsq; // neighbor cutnsq for each ghost type pair - double cutneighmaxsq; // cutneighmax squared - double *cuttypesq; // cuttype squared + bigint last_setup_bins; // step of last neighbor::setup_bins() call double triggersq; // trigger = build when atom moves this dist double **xhold; // atom coords at last neighbor build int maxhold; // size of xhold array + int boxcheck; // 1 if need to store box size double boxlo_hold[3],boxhi_hold[3]; // box size at last neighbor build double corners_hold[8][3]; // box corners at last neighbor build - - int binatomflag; // bin atoms or not when build neigh list - // turned off by build_one() - - int nbinx,nbiny,nbinz; // # of global bins - int *bins; // ptr to next atom in each bin - int maxbin; // size of bins array - - int *binhead; // ptr to 1st atom in each bin - int maxhead; // size of binhead array - - int mbins; // # of local bins and offset - int mbinx,mbiny,mbinz; - int mbinxlo,mbinylo,mbinzlo; - - double binsizex,binsizey,binsizez; // actual bin sizes and inverse sizes - double bininvx,bininvy,bininvz; - - int sx,sy,sz,smax; // bin stencil extents - - int dimension; // 2/3 for 2d/3d - int triclinic; // 0 if domain is orthog, 1 if triclinic - int newton_pair; // 0 if newton off, 1 if on for pairwise - - double *bboxlo,*bboxhi; // ptrs to full domain bounding box - double (*corners)[3]; // ptr to 8 corners of triclinic box + double (*corners)[3]; // ptr to 8 corners of triclinic box double inner[2],middle[2]; // rRESPA cutoffs for extra lists - double cut_inner_sq; // outer cutoff for inner neighbor list - double cut_middle_sq; // outer cutoff for middle neighbor list - double cut_middle_inside_sq; // inner cutoff for middle neighbor list - int special_flag[4]; // flags for 1-2, 1-3, 1-4 neighbors + int same; // 1 if NeighRequests are same as last run + int old_style,old_triclinic; // previous run info + int old_pgsize,old_oneatom; // used to avoid re-creating neigh lists - int anyghostlist; // 1 if any non-occasional list - // stores neighbors of ghosts + int nstencil_perpetual; // # of perpetual NeighStencil classes + int npair_perpetual; // # of perpetual NeighPair classes + int *slist; // indices of them in neigh_stencil + int *plist; // indices of them in neigh_pair - int exclude; // 0 if no type/group exclusions, 1 if yes + int maxex_type; // max # in exclusion type list + int maxex_group; // max # in exclusion group list + int maxex_mol; // max # in exclusion molecule list - int nex_type; // # of entries in type exclusion list - int maxex_type; // max # in type list - int *ex1_type,*ex2_type; // pairs of types to exclude - int **ex_type; // 2d array of excluded type pairs + int maxatom; // size of atom-based NeighList arrays + int maxrequest; // size of NeighRequest list + int maxwt; // max weighting factor applied + 1 - int nex_group; // # of entries in group exclusion list - int maxex_group; // max # in group list - int *ex1_group,*ex2_group; // pairs of group #'s to exclude - int *ex1_bit,*ex2_bit; // pairs of group bits to exclude + // info for other Neigh classes: NBin,NStencil,NPair,NTopo - int nex_mol; // # of entries in molecule exclusion list - int maxex_mol; // max # in molecule list - int *ex_mol_group; // molecule group #'s to exclude - int *ex_mol_bit; // molecule group bits to exclude + int nbin,nstencil; + int nbclass,nsclass,npclass; + int bondwhich,anglewhich,dihedralwhich,improperwhich; - int nblist,nglist,nslist; // # of pairwise neigh lists of various kinds - int *blist; // lists to build every reneighboring - int *glist; // lists to grow atom arrays every reneigh - int *slist; // lists to grow stencil arrays every reneigh + typedef class NBin *(*BinCreator)(class LAMMPS *); + BinCreator *binclass; + char **binnames; + int *binmasks; + class NBin **neigh_bin; - double *zeroes; // vector of zeroes for shear history init + typedef class NStencil *(*StencilCreator)(class LAMMPS *); + StencilCreator *stencilclass; + char **stencilnames; + int *stencilmasks; + class NStencil **neigh_stencil; - // methods + typedef class NPair *(*PairCreator)(class LAMMPS *); + PairCreator *pairclass; + char **pairnames; + int *pairmasks; + class NPair **neigh_pair; - void bin_atoms(); // bin all atoms - double bin_distance(int, int, int); // distance between binx - int coord2bin(double *); // mapping atom coord to a bin - int coord2bin(double *, int &, int &, int&); // ditto + class NTopo *neigh_bond; + class NTopo *neigh_angle; + class NTopo *neigh_dihedral; + class NTopo *neigh_improper; - int exclusion(int, int, int, - int, int *, tagint *) const; // test for pair exclusion + // internal methods + // including creator methods for Nbin,Nstencil,Npair instances - virtual void choose_build(int, class NeighRequest *); - void choose_stencil(int, class NeighRequest *); + void init_styles(); + void init_pair(); + virtual void init_topology(); - // dummy functions provided by NeighborKokkos + void print_pairwise_info(); + void requests_new2old(); - virtual void init_cutneighsq_kokkos(int) {} - virtual int init_lists_kokkos() {return 0;} - virtual void init_list_flags1_kokkos(int) {} - virtual void init_list_flags2_kokkos(int) {} - virtual void init_ex_type_kokkos(int) {} - virtual void init_ex_bit_kokkos() {} - virtual void init_ex_mol_bit_kokkos() {} - virtual void init_list_grow_kokkos(int) {} - virtual void build_kokkos(int) {} - virtual void setup_bins_kokkos(int) {} - virtual void init_topology_kokkos() {} - virtual void build_topology_kokkos() {} + int choose_bin(class NeighRequest *); + int choose_stencil(class NeighRequest *); + int choose_pair(class NeighRequest *); + + template static NBin *bin_creator(class LAMMPS *); + template static NStencil *stencil_creator(class LAMMPS *); + template static NPair *pair_creator(class LAMMPS *); + + // dummy functions provided by NeighborKokkos, called in init() + // otherwise NeighborKokkos would have to overwrite init() int copymode; - // pairwise build functions - - typedef void (Neighbor::*PairPtr)(class NeighList *); - PairPtr *pair_build; - - void half_nsq_no_newton(class NeighList *); - void half_nsq_no_newton_ghost(class NeighList *); - void half_nsq_newton(class NeighList *); - - void half_bin_no_newton(class NeighList *); - void half_bin_no_newton_ghost(class NeighList *); - void half_bin_newton(class NeighList *); - void half_bin_newton_tri(class NeighList *); - - void half_multi_no_newton(class NeighList *); - void half_multi_newton(class NeighList *); - void half_multi_newton_tri(class NeighList *); - - void full_nsq(class NeighList *); - void full_nsq_ghost(class NeighList *); - void full_bin(class NeighList *); - void full_bin_ghost(class NeighList *); - void full_multi(class NeighList *); - - void granular_nsq_no_newton(class NeighList *); - void granular_nsq_newton(class NeighList *); - void granular_nsq_newton_onesided(class NeighList *); - void granular_bin_no_newton(class NeighList *); - void granular_bin_newton(class NeighList *); - void granular_bin_newton_onesided(class NeighList *); - void granular_bin_newton_tri(class NeighList *); - - void respa_nsq_no_newton(class NeighList *); - void respa_nsq_newton(class NeighList *); - void respa_bin_no_newton(class NeighList *); - void respa_bin_newton(class NeighList *); - void respa_bin_newton_tri(class NeighList *); - - void half_from_full_no_newton(class NeighList *); - void half_from_full_newton(class NeighList *); - void skip_from(class NeighList *); - void skip_from_granular(class NeighList *); - void skip_from_granular_off2on(class NeighList *); - void skip_from_granular_off2on_onesided(class NeighList *); - void skip_from_respa(class NeighList *); - void copy_from(class NeighList *); - - // include prototypes for multi-threaded neighbor lists - // builds or their corresponding dummy versions - -#define LMP_INSIDE_NEIGHBOR_H -#include "accelerator_omp.h" -#include "accelerator_intel.h" -#undef LMP_INSIDE_NEIGHBOR_H - - // pairwise stencil creation functions - - typedef void (Neighbor::*StencilPtr)(class NeighList *, int, int, int); - StencilPtr *stencil_create; - - void stencil_half_bin_2d_no_newton(class NeighList *, int, int, int); - void stencil_half_ghost_bin_2d_no_newton(class NeighList *, int, int, int); - void stencil_half_bin_3d_no_newton(class NeighList *, int, int, int); - void stencil_half_ghost_bin_3d_no_newton(class NeighList *, int, int, int); - void stencil_half_bin_2d_newton(class NeighList *, int, int, int); - void stencil_half_bin_3d_newton(class NeighList *, int, int, int); - void stencil_half_bin_2d_newton_tri(class NeighList *, int, int, int); - void stencil_half_bin_3d_newton_tri(class NeighList *, int, int, int); - - void stencil_half_multi_2d_no_newton(class NeighList *, int, int, int); - void stencil_half_multi_3d_no_newton(class NeighList *, int, int, int); - void stencil_half_multi_2d_newton(class NeighList *, int, int, int); - void stencil_half_multi_3d_newton(class NeighList *, int, int, int); - void stencil_half_multi_2d_newton_tri(class NeighList *, int, int, int); - void stencil_half_multi_3d_newton_tri(class NeighList *, int, int, int); - - void stencil_full_bin_2d(class NeighList *, int, int, int); - void stencil_full_ghost_bin_2d(class NeighList *, int, int, int); - void stencil_full_bin_3d(class NeighList *, int, int, int); - void stencil_full_ghost_bin_3d(class NeighList *, int, int, int); - void stencil_full_multi_2d(class NeighList *, int, int, int); - void stencil_full_multi_3d(class NeighList *, int, int, int); - - // topology build functions - - typedef void (Neighbor::*BondPtr)(); // ptrs to topology build functions - - BondPtr bond_build; // ptr to bond list functions - void bond_all(); // bond list with all bonds - void bond_template(); // bond list with templated bonds - void bond_partial(); // exclude certain bonds - void bond_check(); - - BondPtr angle_build; // ptr to angle list functions - void angle_all(); // angle list with all angles - void angle_template(); // angle list with templated bonds - void angle_partial(); // exclude certain angles - void angle_check(); - - BondPtr dihedral_build; // ptr to dihedral list functions - void dihedral_all(); // dihedral list with all dihedrals - void dihedral_template(); // dihedral list with templated bonds - void dihedral_partial(); // exclude certain dihedrals - void dihedral_check(int, int **); - - BondPtr improper_build; // ptr to improper list functions - void improper_all(); // improper list with all impropers - void improper_template(); // improper list with templated bonds - void improper_partial(); // exclude certain impropers - - // SSA neighboring for USER-DPD - - void half_bin_newton_ssa(NeighList *); - void half_from_full_newton_ssa(class NeighList *); - void stencil_half_bin_2d_ssa(class NeighList *, int, int, int); - void stencil_half_bin_3d_ssa(class NeighList *, int, int, int); - - // find_special: determine if atom j is in special list of atom i - // if it is not, return 0 - // if it is and special flag is 0 (both coeffs are 0.0), return -1 - // if it is and special flag is 1 (both coeffs are 1.0), return 0 - // if it is and special flag is 2 (otherwise), return 1,2,3 - // for which level of neighbor it is (and which coeff it maps to) - - inline int find_special(const tagint *list, const int *nspecial, - const tagint tag) const { - const int n1 = nspecial[0]; - const int n2 = nspecial[1]; - const int n3 = nspecial[2]; - - for (int i = 0; i < n3; i++) { - if (list[i] == tag) { - if (i < n1) { - if (special_flag[1] == 0) return -1; - else if (special_flag[1] == 1) return 0; - else return 1; - } else if (i < n2) { - if (special_flag[2] == 0) return -1; - else if (special_flag[2] == 1) return 0; - else return 2; - } else { - if (special_flag[3] == 0) return -1; - else if (special_flag[3] == 1) return 0; - else return 3; - } - } - } - return 0; - }; + virtual void init_cutneighsq_kokkos(int) {} + virtual void create_kokkos_list(int) {} + virtual void init_ex_type_kokkos(int) {} + virtual void init_ex_bit_kokkos() {} + virtual void init_ex_mol_bit_kokkos() {} }; +namespace NeighConst { + static const int NB_SSA = 1<<0; + static const int NB_INTEL = 1<<1; + static const int NB_KOKKOS_DEVICE = 1<<2; + static const int NB_KOKKOS_HOST = 1<<3; + + static const int NS_HALF = 1<<0; + static const int NS_FULL = 1<<1; + static const int NS_GHOST = 1<<2; + static const int NS_SSA = 1<<3; + static const int NS_BIN = 1<<4; + static const int NS_MULTI = 1<<5; + static const int NS_2D = 1<<6; + static const int NS_3D = 1<<7; + static const int NS_NEWTON = 1<<8; + static const int NS_NEWTOFF = 1<<9; + static const int NS_ORTHO = 1<<10; + static const int NS_TRI = 1<<11; + + static const int NP_COPY = 1<<0; + static const int NP_SKIP = 1<<1; + static const int NP_HALF = 1<<2; + static const int NP_FULL = 1<<3; + static const int NP_HALFFULL = 1<<4; + static const int NP_SIZE = 1<<5; + static const int NP_RESPA = 1<<6; + static const int NP_GHOST = 1<<7; + static const int NP_OFF2ON = 1<<8; + static const int NP_ONESIDE = 1<<9; + static const int NP_SSA = 1<<10; + static const int NP_OMP = 1<<11; + static const int NP_INTEL = 1<<12; + static const int NP_NSQ = 1<<13; + static const int NP_BIN = 1<<14; + static const int NP_MULTI = 1<<15; + static const int NP_NEWTON = 1<<16; + static const int NP_NEWTOFF = 1<<17; + static const int NP_ORTHO = 1<<18; + static const int NP_TRI = 1<<19; + static const int NP_KOKKOS_DEVICE = 1<<20; + static const int NP_KOKKOS_HOST = 1<<21; +} + } #endif diff --git a/src/npair.cpp b/src/npair.cpp new file mode 100644 index 0000000000..6ea4e62550 --- /dev/null +++ b/src/npair.cpp @@ -0,0 +1,257 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair.h" +#include "neighbor.h" +#include "nbin.h" +#include "nstencil.h" +#include "atom.h" +#include "update.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPair::NPair(LAMMPS *lmp) : Pointers(lmp) +{ + last_build = -1; + last_copy_bin_setup = last_copy_bin = last_copy_stencil = -1; + + molecular = atom->molecular; +} + +/* ---------------------------------------------------------------------- + copy needed info from Neighbor class to this build class +------------------------------------------------------------------------- */ + +void NPair::copy_neighbor_info() +{ + // general params + + includegroup = neighbor->includegroup; + exclude = neighbor->exclude; + skin = neighbor->skin; + cutneighsq = neighbor->cutneighsq; + cutneighghostsq = neighbor->cutneighghostsq; + cut_inner_sq = neighbor->cut_inner_sq; + cut_middle_sq = neighbor->cut_middle_sq; + cut_middle_inside_sq = neighbor->cut_middle_inside_sq; + zeroes = neighbor->zeroes; + bboxlo = neighbor->bboxlo; + bboxhi = neighbor->bboxhi; + + // exclusion info + + nex_type = neighbor->nex_type; + ex1_type = neighbor->ex1_type; + ex2_type = neighbor->ex2_type; + ex_type = neighbor->ex_type; + + nex_group = neighbor->nex_group; + ex1_group = neighbor->ex1_group; + ex2_group = neighbor->ex2_group; + ex1_bit = neighbor->ex1_bit; + ex2_bit = neighbor->ex2_bit; + + nex_mol = neighbor->nex_mol; + ex_mol_group = neighbor->ex_mol_group; + ex_mol_bit = neighbor->ex_mol_bit; + + // special info + + special_flag = neighbor->special_flag; +} + +/* ---------------------------------------------------------------------- + copy bin geometry info from NBin class to this build class +------------------------------------------------------------------------- */ + +void NPair::copy_bin_setup_info() +{ + nbinx = nb->nbinx; + nbiny = nb->nbiny; + nbinz = nb->nbinz; + mbins = nb->mbins; + mbinx = nb->mbinx; + mbiny = nb->mbiny; + mbinz = nb->mbinz; + mbinxlo = nb->mbinxlo; + mbinylo = nb->mbinylo; + mbinzlo = nb->mbinzlo; + + bininvx = nb->bininvx; + bininvy = nb->bininvy; + bininvz = nb->bininvz; +} + +/* ---------------------------------------------------------------------- + copy per-atom and per-bin vectors from NBin class to this build class +------------------------------------------------------------------------- */ + +void NPair::copy_bin_info() +{ + bins = nb->bins; + binhead = nb->binhead; +} + +/* ---------------------------------------------------------------------- + copy needed info from NStencil class to this build class +------------------------------------------------------------------------- */ + +void NPair::copy_stencil_info() +{ + nstencil = ns->nstencil; + stencil = ns->stencil; + stencilxyz = ns->stencilxyz; + nstencil_multi = ns->nstencil_multi; + stencil_multi = ns->stencil_multi; + distsq_multi = ns->distsq_multi; +} + +/* ---------------------------------------------------------------------- + copy needed info from NStencil class to this build class +------------------------------------------------------------------------- */ + +void NPair::build_setup() +{ + if (nb && last_copy_bin_setup < nb->last_setup) { + copy_bin_setup_info(); + last_copy_bin_setup = update->ntimestep; + } + if (nb && last_copy_bin < nb->last_bin_memory) { + copy_bin_info(); + last_copy_bin = update->ntimestep; + } + if (ns && last_copy_stencil < ns->last_create) { + copy_stencil_info(); + last_copy_stencil = update->ntimestep; + } + + last_build = update->ntimestep; +} + +/* ---------------------------------------------------------------------- + test if atom pair i,j is excluded from neighbor list + due to type, group, molecule settings from neigh_modify command + return 1 if should be excluded, 0 if included +------------------------------------------------------------------------- */ + +int NPair::exclusion(int i, int j, int itype, int jtype, + int *mask, tagint *molecule) const { + int m; + + if (nex_type && ex_type[itype][jtype]) return 1; + + if (nex_group) { + for (m = 0; m < nex_group; m++) { + if (mask[i] & ex1_bit[m] && mask[j] & ex2_bit[m]) return 1; + if (mask[i] & ex2_bit[m] && mask[j] & ex1_bit[m]) return 1; + } + } + + if (nex_mol) { + for (m = 0; m < nex_mol; m++) + if (mask[i] & ex_mol_bit[m] && mask[j] & ex_mol_bit[m] && + molecule[i] == molecule[j]) return 1; + } + + return 0; +} + +/* ---------------------------------------------------------------------- + convert atom coords into local bin # + for orthogonal, only ghost atoms will have coord >= bboxhi or coord < bboxlo + take special care to insure ghosts are in correct bins even w/ roundoff + hi ghost atoms = nbin,nbin+1,etc + owned atoms = 0 to nbin-1 + lo ghost atoms = -1,-2,etc + this is necessary so that both procs on either side of PBC + treat a pair of atoms straddling the PBC in a consistent way + for triclinic, doesn't matter since stencil & neigh list built differently +------------------------------------------------------------------------- */ + +int NPair::coord2bin(double *x) +{ + int ix,iy,iz; + + if (!ISFINITE(x[0]) || !ISFINITE(x[1]) || !ISFINITE(x[2])) + error->one(FLERR,"Non-numeric positions - simulation unstable"); + + if (x[0] >= bboxhi[0]) + ix = static_cast ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast ((x[0]-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast ((x[1]-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast ((x[2]-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((x[2]-bboxlo[2])*bininvz) - 1; + + return (iz-mbinzlo)*mbiny*mbinx + (iy-mbinylo)*mbinx + (ix-mbinxlo); +} + +/* ---------------------------------------------------------------------- + same as coord2bin, but also return ix,iy,iz offsets in each dim +------------------------------------------------------------------------- */ + +int NPair::coord2bin(double *x, int &ix, int &iy, int &iz) +{ + if (!ISFINITE(x[0]) || !ISFINITE(x[1]) || !ISFINITE(x[2])) + error->one(FLERR,"Non-numeric positions - simulation unstable"); + + if (x[0] >= bboxhi[0]) + ix = static_cast ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast ((x[0]-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast ((x[1]-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast ((x[2]-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast ((x[2]-bboxlo[2])*bininvz) - 1; + + ix -= mbinxlo; + iy -= mbinylo; + iz -= mbinzlo; + return iz*mbiny*mbinx + iy*mbinx + ix; +} + diff --git a/src/npair.h b/src/npair.h new file mode 100644 index 0000000000..a6440faddf --- /dev/null +++ b/src/npair.h @@ -0,0 +1,145 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_NPAIR_H +#define LMP_NPAIR_H + +#include "pointers.h" + +namespace LAMMPS_NS { + +class NPair : protected Pointers { + public: + int istyle; // 1-N index into pairnames + class NBin *nb; // ptr to NBin instance I depend on + class NStencil *ns; // ptr to NStencil instance I depend on + + bigint last_build; // last timestep build performed + bigint last_copy_bin_setup; // last timestep I invoked copy_bin_setup_info() + bigint last_copy_bin; // last step I invoked copy_bin_info() + bigint last_copy_stencil; // last step I invoked copy_bin_stencil_info() + + NPair(class LAMMPS *); + virtual ~NPair() {} + virtual void copy_neighbor_info(); + void build_setup(); + virtual void build(class NeighList *) = 0; + + protected: + + // data from Neighbor class + + int includegroup; + int exclude; + double skin; + double **cutneighsq; + double **cutneighghostsq; + double cut_inner_sq; + double cut_middle_sq; + double cut_middle_inside_sq; + double *zeroes; + double *bboxlo,*bboxhi; + + // exclusion data from Neighbor class + + int nex_type; // # of entries in type exclusion list + int *ex1_type,*ex2_type; // pairs of types to exclude + int **ex_type; // 2d array of excluded type pairs + + int nex_group; // # of entries in group exclusion list + int *ex1_group,*ex2_group; // pairs of group #'s to exclude + int *ex1_bit,*ex2_bit; // pairs of group bits to exclude + + int nex_mol; // # of entries in molecule exclusion list + int *ex_mol_group; // molecule group #'s to exclude + int *ex_mol_bit; // molecule group bits to exclude + + // special data from Neighbor class + + int *special_flag; + + // data from NBin class + + int nbinx,nbiny,nbinz; + int mbins; + int mbinx,mbiny,mbinz; + int mbinxlo,mbinylo,mbinzlo; + double bininvx,bininvy,bininvz; + int *bins; + int *binhead; + + // data from NStencil class + + int nstencil; + int *stencil; + int **stencilxyz; + int *nstencil_multi; + int **stencil_multi; + double **distsq_multi; + + // data common to all NPair variants + + int molecular; + + // methods for all NPair variants + + void copy_bin_setup_info(); + virtual void copy_bin_info(); + virtual void copy_stencil_info(); + + int exclusion(int, int, int, + int, int *, tagint *) const; // test for pair exclusion + int coord2bin(double *); // mapping atom coord to a bin + int coord2bin(double *, int &, int &, int&); // ditto + + // find_special: determine if atom j is in special list of atom i + // if it is not, return 0 + // if it is and special flag is 0 (both coeffs are 0.0), return -1 + // if it is and special flag is 1 (both coeffs are 1.0), return 0 + // if it is and special flag is 2 (otherwise), return 1,2,3 + // for which level of neighbor it is (and which coeff it maps to) + + inline int find_special(const tagint *list, const int *nspecial, + const tagint tag) const { + const int n1 = nspecial[0]; + const int n2 = nspecial[1]; + const int n3 = nspecial[2]; + + for (int i = 0; i < n3; i++) { + if (list[i] == tag) { + if (i < n1) { + if (special_flag[1] == 0) return -1; + else if (special_flag[1] == 1) return 0; + else return 1; + } else if (i < n2) { + if (special_flag[2] == 0) return -1; + else if (special_flag[2] == 1) return 0; + else return 2; + } else { + if (special_flag[3] == 0) return -1; + else if (special_flag[3] == 1) return 0; + else return 3; + } + } + } + return 0; + }; +}; + +} + +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_copy.cpp b/src/npair_copy.cpp new file mode 100644 index 0000000000..1799d48fed --- /dev/null +++ b/src/npair_copy.cpp @@ -0,0 +1,46 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_copy.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; + +/* ---------------------------------------------------------------------- */ + +NPairCopy::NPairCopy(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + create list which is simply a copy of parent list +------------------------------------------------------------------------- */ + +void NPairCopy::build(NeighList *list) +{ + NeighList *listcopy = list->listcopy; + + list->inum = listcopy->inum; + list->gnum = listcopy->gnum; + list->ilist = listcopy->ilist; + list->numneigh = listcopy->numneigh; + list->firstneigh = listcopy->firstneigh; + list->firstdouble = listcopy->firstdouble; + list->ipage = listcopy->ipage; + list->dpage = listcopy->dpage; +} diff --git a/src/neigh_half_bin.h b/src/npair_copy.h similarity index 67% rename from src/neigh_half_bin.h rename to src/npair_copy.h index 1538f7662a..62467c2d20 100644 --- a/src/neigh_half_bin.h +++ b/src/npair_copy.h @@ -11,12 +11,33 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#ifdef NPAIR_CLASS + +NPairStyle(copy, + NPairCopy, + NP_COPY) + +#else + +#ifndef LMP_NPAIR_COPY_H +#define LMP_NPAIR_COPY_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairCopy : public NPair { + public: + NPairCopy(class LAMMPS *); + ~NPairCopy() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + /* ERROR/WARNING messages: -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - */ diff --git a/src/npair_full_bin.cpp b/src/npair_full_bin.cpp new file mode 100644 index 0000000000..a29acb67ab --- /dev/null +++ b/src/npair_full_bin.cpp @@ -0,0 +1,125 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_bin.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; + +/* ---------------------------------------------------------------------- */ + +NPairFullBin::NPairFullBin(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction for all neighbors + every neighbor pair appears in list of both atoms i and j +------------------------------------------------------------------------- */ + +void NPairFullBin::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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 = coord2bin(x[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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + list->gnum = 0; +} diff --git a/src/npair_full_bin.h b/src/npair_full_bin.h new file mode 100644 index 0000000000..c6acde578c --- /dev/null +++ b/src/npair_full_bin.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/bin, + NPairFullBin, + NP_FULL | NP_BIN | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_FULL_BIN_H +#define LMP_NPAIR_FULL_BIN_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairFullBin : public NPair { + public: + NPairFullBin(class LAMMPS *); + ~NPairFullBin() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_full_bin_ghost.cpp b/src/npair_full_bin_ghost.cpp new file mode 100644 index 0000000000..1e258cf518 --- /dev/null +++ b/src/npair_full_bin_ghost.cpp @@ -0,0 +1,156 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_bin_ghost.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; + +/* ---------------------------------------------------------------------- */ + +NPairFullBinGhost::NPairFullBinGhost(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 +------------------------------------------------------------------------- */ + +void NPairFullBinGhost::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int xbin,ybin,zbin,xbin2,ybin2,zbin2; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + // loop over owned & ghost atoms, storing neighbors + + for (i = 0; i < nall; 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 + // 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 = coord2bin(x[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) { + 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 (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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = atom->nlocal; + list->gnum = inum - atom->nlocal; +} diff --git a/src/npair_full_bin_ghost.h b/src/npair_full_bin_ghost.h new file mode 100644 index 0000000000..a09aab8512 --- /dev/null +++ b/src/npair_full_bin_ghost.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/bin/ghost, + NPairFullBinGhost, + NP_FULL | NP_BIN | NP_GHOST | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_FULL_BIN_GHOST_H +#define LMP_NPAIR_FULL_BIN_GHOST_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairFullBinGhost : public NPair { + public: + NPairFullBinGhost(class LAMMPS *); + ~NPairFullBinGhost() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_full_multi.cpp b/src/npair_full_multi.cpp new file mode 100644 index 0000000000..628a706e7a --- /dev/null +++ b/src/npair_full_multi.cpp @@ -0,0 +1,132 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_multi.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; + +/* ---------------------------------------------------------------------- */ + +NPairFullMulti::NPairFullMulti(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + binned neighbor list construction for all neighbors + multi-type stencil is itype dependent and is distance checked + every neighbor pair appears in list of both atoms i and j +------------------------------------------------------------------------- */ + +void NPairFullMulti::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; + tagint 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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 + // skip if i,j neighbor cutoff is less than bin distance + // skip i = j + + ibin = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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 (i == j) 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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + list->gnum = 0; +} diff --git a/src/npair_full_multi.h b/src/npair_full_multi.h new file mode 100644 index 0000000000..c778978c01 --- /dev/null +++ b/src/npair_full_multi.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/multi, + NPairFullMulti, + NP_FULL | NP_MULTI | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_FULL_MULTI_H +#define LMP_NPAIR_FULL_MULTI_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairFullMulti : public NPair { + public: + NPairFullMulti(class LAMMPS *); + ~NPairFullMulti() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_full_nsq.cpp b/src/npair_full_nsq.cpp new file mode 100644 index 0000000000..1b404ffc94 --- /dev/null +++ b/src/npair_full_nsq.cpp @@ -0,0 +1,125 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_nsq.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +NPairFullNsq::NPairFullNsq(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + N^2 search for all neighbors + every neighbor pair appears in list of both atoms i and j +------------------------------------------------------------------------- */ + +void NPairFullNsq::build(NeighList *list) +{ + int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + list->gnum = 0; +} diff --git a/src/npair_full_nsq.h b/src/npair_full_nsq.h new file mode 100644 index 0000000000..a1eaf8463a --- /dev/null +++ b/src/npair_full_nsq.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/nsq, + NPairFullNsq, + NP_FULL | NP_NSQ | NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_FULL_NSQ_H +#define LMP_NPAIR_FULL_NSQ_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairFullNsq : public NPair { + public: + NPairFullNsq(class LAMMPS *); + ~NPairFullNsq() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_full_nsq_ghost.cpp b/src/npair_full_nsq_ghost.cpp new file mode 100644 index 0000000000..1727b2905e --- /dev/null +++ b/src/npair_full_nsq_ghost.cpp @@ -0,0 +1,138 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_full_nsq_ghost.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; + +/* ---------------------------------------------------------------------- */ + +NPairFullNsqGhost::NPairFullNsqGhost(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 NPairFullNsqGhost::build(NeighList *list) +{ + int i,j,n,itype,jtype,which,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + // loop over owned & ghost atoms, storing neighbors + + for (i = 0; i < nall; 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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = atom->nlocal; + list->gnum = inum - atom->nlocal; +} diff --git a/src/npair_full_nsq_ghost.h b/src/npair_full_nsq_ghost.h new file mode 100644 index 0000000000..3e259ed098 --- /dev/null +++ b/src/npair_full_nsq_ghost.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(full/nsq/ghost, + NPairFullNsqGhost, + NP_FULL | NP_NSQ | NP_GHOST | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_FULL_NSQ_GHOST_H +#define LMP_NPAIR_FULL_NSQ_GHOST_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairFullNsqGhost : public NPair { + public: + NPairFullNsqGhost(class LAMMPS *); + ~NPairFullNsqGhost() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_bin_newtoff.cpp b/src/npair_half_bin_newtoff.cpp new file mode 100644 index 0000000000..dd072508a9 --- /dev/null +++ b/src/npair_half_bin_newtoff.cpp @@ -0,0 +1,129 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newtoff.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtoff::NPairHalfBinNewtoff(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 NPairHalfBinNewtoff::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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 = coord2bin(x[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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_bin_newtoff.h b/src/npair_half_bin_newtoff.h new file mode 100644 index 0000000000..f6025ac095 --- /dev/null +++ b/src/npair_half_bin_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newtoff, + NPairHalfBinNewtoff, + NP_HALF | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_H +#define LMP_NPAIR_HALF_BIN_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewtoff : public NPair { + public: + NPairHalfBinNewtoff(class LAMMPS *); + ~NPairHalfBinNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_bin_newtoff_ghost.cpp b/src/npair_half_bin_newtoff_ghost.cpp new file mode 100644 index 0000000000..f486df105a --- /dev/null +++ b/src/npair_half_bin_newtoff_ghost.cpp @@ -0,0 +1,162 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newtoff_ghost.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtoffGhost::NPairHalfBinNewtoffGhost(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 NPairHalfBinNewtoffGhost::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int xbin,ybin,zbin,xbin2,ybin2,zbin2; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nall; 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 = coord2bin(x[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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = atom->nlocal; + list->gnum = inum - atom->nlocal; +} diff --git a/src/npair_half_bin_newtoff_ghost.h b/src/npair_half_bin_newtoff_ghost.h new file mode 100644 index 0000000000..ffdf097f7e --- /dev/null +++ b/src/npair_half_bin_newtoff_ghost.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newtoff/ghost, + NPairHalfBinNewtoffGhost, + NP_HALF | NP_BIN | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_H +#define LMP_NPAIR_HALF_BIN_NEWTOFF_GHOST_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewtoffGhost : public NPair { + public: + NPairHalfBinNewtoffGhost(class LAMMPS *); + ~NPairHalfBinNewtoffGhost() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_bin_newton.cpp b/src/npair_half_bin_newton.cpp new file mode 100644 index 0000000000..f1fc203403 --- /dev/null +++ b/src/npair_half_bin_newton.cpp @@ -0,0 +1,161 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newton.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewton::NPairHalfBinNewton(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 NPairHalfBinNewton::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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) { + 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 = coord2bin(x[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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_bin_newton.h b/src/npair_half_bin_newton.h new file mode 100644 index 0000000000..c20e3dbef5 --- /dev/null +++ b/src/npair_half_bin_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newton, + NPairHalfBinNewton, + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTON_H +#define LMP_NPAIR_HALF_BIN_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewton : public NPair { + public: + NPairHalfBinNewton(class LAMMPS *); + ~NPairHalfBinNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_bin_newton_tri.cpp b/src/npair_half_bin_newton_tri.cpp new file mode 100644 index 0000000000..3ef8c3260e --- /dev/null +++ b/src/npair_half_bin_newton_tri.cpp @@ -0,0 +1,134 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_bin_newton_tri.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfBinNewtonTri::NPairHalfBinNewtonTri(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 NPairHalfBinNewtonTri::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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 bins in stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && 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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_bin_newton_tri.h b/src/npair_half_bin_newton_tri.h new file mode 100644 index 0000000000..e6b09f58f4 --- /dev/null +++ b/src/npair_half_bin_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/bin/newton/tri, + NPairHalfBinNewtonTri, + NP_HALF | NP_BIN | NP_NEWTON | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_BIN_NEWTON_TRI_H +#define LMP_NPAIR_HALF_BIN_NEWTON_TRI_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfBinNewtonTri : public NPair { + public: + NPairHalfBinNewtonTri(class LAMMPS *); + ~NPairHalfBinNewtonTri() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_multi_newtoff.cpp b/src/npair_half_multi_newtoff.cpp new file mode 100644 index 0000000000..11e45d91ff --- /dev/null +++ b/src/npair_half_multi_newtoff.cpp @@ -0,0 +1,135 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_multi_newtoff.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfMultiNewtoff::NPairHalfMultiNewtoff(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 NPairHalfMultiNewtoff::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; + tagint 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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 = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_multi_newtoff.h b/src/npair_half_multi_newtoff.h new file mode 100644 index 0000000000..4c57c9bfe7 --- /dev/null +++ b/src/npair_half_multi_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/multi/newtoff, + NPairHalfMultiNewtoff, + NP_HALF | NP_MULTI | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_MULTI_NEWTOFF_H +#define LMP_NPAIR_HALF_MULTI_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfMultiNewtoff : public NPair { + public: + NPairHalfMultiNewtoff(class LAMMPS *); + ~NPairHalfMultiNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_multi_newton.cpp b/src/npair_half_multi_newton.cpp new file mode 100644 index 0000000000..cd3a37821f --- /dev/null +++ b/src/npair_half_multi_newton.cpp @@ -0,0 +1,168 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_multi_newton.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfMultiNewton::NPairHalfMultiNewton(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 NPairHalfMultiNewton::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; + tagint 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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) { + 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 = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_multi_newton.h b/src/npair_half_multi_newton.h new file mode 100644 index 0000000000..64021a9f58 --- /dev/null +++ b/src/npair_half_multi_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/multi/newton, + NPairHalfMultiNewton, + NP_HALF | NP_MULTI | NP_NEWTON | NP_ORTHO) + +#else + +#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_H +#define LMP_NPAIR_HALF_MULTI_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfMultiNewton : public NPair { + public: + NPairHalfMultiNewton(class LAMMPS *); + ~NPairHalfMultiNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_multi_newton_tri.cpp b/src/npair_half_multi_newton_tri.cpp new file mode 100644 index 0000000000..f9aaeb0414 --- /dev/null +++ b/src/npair_half_multi_newton_tri.cpp @@ -0,0 +1,143 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_multi_newton_tri.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfMultiNewtonTri::NPairHalfMultiNewtonTri(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 NPairHalfMultiNewtonTri::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,which,ns,imol,iatom,moltemplate; + tagint 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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 bins, including self, in stencil + // skip if i,j neighbor cutoff is less than bin distance + // bins below self are excluded from stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + cutsq = cutneighsq[itype]; + ns = nstencil_multi[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 (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && j <= i) 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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_multi_newton_tri.h b/src/npair_half_multi_newton_tri.h new file mode 100644 index 0000000000..51b720e0c4 --- /dev/null +++ b/src/npair_half_multi_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/multi/newton/tri, + NPairHalfMultiNewtonTri, + NP_HALF | NP_MULTI | NP_NEWTON | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_MULTI_NEWTON_TRI_H +#define LMP_NPAIR_HALF_MULTI_NEWTON_TRI_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfMultiNewtonTri : public NPair { + public: + NPairHalfMultiNewtonTri(class LAMMPS *); + ~NPairHalfMultiNewtonTri() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_nsq_newtoff.cpp b/src/npair_half_nsq_newtoff.cpp new file mode 100644 index 0000000000..06e8344332 --- /dev/null +++ b/src/npair_half_nsq_newtoff.cpp @@ -0,0 +1,125 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_nsq_newtoff.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfNsqNewtoff::NPairHalfNsqNewtoff(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 NPairHalfNsqNewtoff::build(NeighList *list) +{ + int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_nsq_newtoff.h b/src/npair_half_nsq_newtoff.h new file mode 100644 index 0000000000..90a1990f7f --- /dev/null +++ b/src/npair_half_nsq_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/nsq/newtoff, + NPairHalfNsqNewtoff, + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_H +#define LMP_NPAIR_HALF_NSQ_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfNsqNewtoff : public NPair { + public: + NPairHalfNsqNewtoff(class LAMMPS *); + ~NPairHalfNsqNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_nsq_newtoff_ghost.cpp b/src/npair_half_nsq_newtoff_ghost.cpp new file mode 100644 index 0000000000..1865061a8b --- /dev/null +++ b/src/npair_half_nsq_newtoff_ghost.cpp @@ -0,0 +1,150 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_nsq_newtoff_ghost.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfNsqNewtoffGhost::NPairHalfNsqNewtoffGhost(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 NPairHalfNsqNewtoffGhost::build(NeighList *list) +{ + int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + // loop over owned & ghost atoms, storing neighbors + + for (i = 0; i < nall; 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) { + 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[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = atom->nlocal; + list->gnum = inum - atom->nlocal; +} diff --git a/src/npair_half_nsq_newtoff_ghost.h b/src/npair_half_nsq_newtoff_ghost.h new file mode 100644 index 0000000000..e772b4b5c4 --- /dev/null +++ b/src/npair_half_nsq_newtoff_ghost.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/nsq/newtoff/ghost, + NPairHalfNsqNewtoffGhost, + NP_HALF | NP_NSQ | NP_NEWTOFF | NP_GHOST | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_H +#define LMP_NPAIR_HALF_NSQ_NEWTOFF_GHOST_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfNsqNewtoffGhost : public NPair { + public: + NPairHalfNsqNewtoffGhost(class LAMMPS *); + ~NPairHalfNsqNewtoffGhost() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_nsq_newton.cpp b/src/npair_half_nsq_newton.cpp new file mode 100644 index 0000000000..11c71d5609 --- /dev/null +++ b/src/npair_half_nsq_newton.cpp @@ -0,0 +1,142 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_nsq_newton.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfNsqNewton::NPairHalfNsqNewton(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 NPairHalfNsqNewton::build(NeighList *list) +{ + int i,j,n,itype,jtype,which,bitmask,imol,iatom,moltemplate; + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int inum = 0; + ipage->reset(); + + for (i = 0; i < nlocal; 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 + // itag = jtag is possible for long cutoffs that include images of self + + 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 (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; + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_half_nsq_newton.h b/src/npair_half_nsq_newton.h new file mode 100644 index 0000000000..7373c44f1a --- /dev/null +++ b/src/npair_half_nsq_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/nsq/newton, + NPairHalfNsqNewton, + NP_HALF | NP_NSQ | NP_NEWTON | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_NSQ_NEWTON_H +#define LMP_NPAIR_HALF_NSQ_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfNsqNewton : public NPair { + public: + NPairHalfNsqNewton(class LAMMPS *); + ~NPairHalfNsqNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_respa_bin_newtoff.cpp b/src/npair_half_respa_bin_newtoff.cpp new file mode 100644 index 0000000000..39f68a289d --- /dev/null +++ b/src/npair_half_respa_bin_newtoff.cpp @@ -0,0 +1,190 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_bin_newtoff.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfRespaBinNewtoff::NPairHalfRespaBinNewtoff(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 NPairHalfRespaBinNewtoff::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr,*neighptr_inner,*neighptr_middle; + + 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + ipage_middle = listmiddle->ipage; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; 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 = coord2bin(x[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) { + 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[inum] = 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[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = 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"); + } + + inum++; + } + + list->inum = inum; + listinner->inum = inum; + if (respamiddle) listmiddle->inum = inum; +} diff --git a/src/npair_half_respa_bin_newtoff.h b/src/npair_half_respa_bin_newtoff.h new file mode 100644 index 0000000000..290783d8fe --- /dev/null +++ b/src/npair_half_respa_bin_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/bin/newtoff, + NPairHalfRespaBinNewtoff, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_H +#define LMP_NPAIR_HALF_RESPA_BIN_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfRespaBinNewtoff : public NPair { + public: + NPairHalfRespaBinNewtoff(class LAMMPS *); + ~NPairHalfRespaBinNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_respa_bin_newton.cpp b/src/npair_half_respa_bin_newton.cpp new file mode 100644 index 0000000000..537a72d0c1 --- /dev/null +++ b/src/npair_half_respa_bin_newton.cpp @@ -0,0 +1,236 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_bin_newton.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfRespaBinNewton::NPairHalfRespaBinNewton(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 NPairHalfRespaBinNewton::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr,*neighptr_inner,*neighptr_middle; + + 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + ipage_middle = listmiddle->ipage; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; 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) { + 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 = coord2bin(x[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) { + 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[inum] = 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[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = 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"); + } + + inum++; + } + + list->inum = inum; + listinner->inum = inum; + if (respamiddle) listmiddle->inum = inum; +} diff --git a/src/npair_half_respa_bin_newton.h b/src/npair_half_respa_bin_newton.h new file mode 100644 index 0000000000..d1566ee943 --- /dev/null +++ b/src/npair_half_respa_bin_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/bin/newton, + NPairHalfRespaBinNewton, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_ORTHO) + +#else + +#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_H +#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfRespaBinNewton : public NPair { + public: + NPairHalfRespaBinNewton(class LAMMPS *); + ~NPairHalfRespaBinNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_respa_bin_newton_tri.cpp b/src/npair_half_respa_bin_newton_tri.cpp new file mode 100644 index 0000000000..9c5fd39fbe --- /dev/null +++ b/src/npair_half_respa_bin_newton_tri.cpp @@ -0,0 +1,198 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_bin_newton_tri.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfRespaBinNewtonTri::NPairHalfRespaBinNewtonTri(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multiple respa lists + 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 NPairHalfRespaBinNewtonTri::build(NeighList *list) +{ + int i,j,k,n,itype,jtype,ibin,n_inner,n_middle,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr,*neighptr_inner,*neighptr_middle; + + 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 nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + ipage_middle = listmiddle->ipage; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; 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 all atoms in bins in stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && 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) { + 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[inum] = 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[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = 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"); + } + + inum++; + } + + list->inum = inum; + listinner->inum = inum; + if (respamiddle) listmiddle->inum = inum; +} diff --git a/src/npair_half_respa_bin_newton_tri.h b/src/npair_half_respa_bin_newton_tri.h new file mode 100644 index 0000000000..779a3cd1db --- /dev/null +++ b/src/npair_half_respa_bin_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/bin/newton/tri, + NPairHalfRespaBinNewtonTri, + NP_HALF | NP_RESPA | NP_BIN | NP_NEWTON | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_H +#define LMP_NPAIR_HALF_RESPA_BIN_NEWTON_TRI_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfRespaBinNewtonTri : public NPair { + public: + NPairHalfRespaBinNewtonTri(class LAMMPS *); + ~NPairHalfRespaBinNewtonTri() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_respa_nsq_newtoff.cpp b/src/npair_half_respa_nsq_newtoff.cpp new file mode 100644 index 0000000000..1bb2034384 --- /dev/null +++ b/src/npair_half_respa_nsq_newtoff.cpp @@ -0,0 +1,185 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_nsq_newtoff.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfRespaNsqNewtoff::NPairHalfRespaNsqNewtoff(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 NPairHalfRespaNsqNewtoff::build(NeighList *list) +{ + int i,j,n,itype,jtype,n_inner,n_middle,bitmask,imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr,*neighptr_inner,*neighptr_middle; + + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + ipage_middle = listmiddle->ipage; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; 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) { + 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[inum] = 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[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = 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"); + } + + inum++; + } + + list->inum = inum; + listinner->inum = inum; + if (respamiddle) listmiddle->inum = inum; +} diff --git a/src/npair_half_respa_nsq_newtoff.h b/src/npair_half_respa_nsq_newtoff.h new file mode 100644 index 0000000000..71f936c4ae --- /dev/null +++ b/src/npair_half_respa_nsq_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/nsq/newtoff, + NPairHalfRespaNsqNewtoff, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_H +#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfRespaNsqNewtoff : public NPair { + public: + NPairHalfRespaNsqNewtoff(class LAMMPS *); + ~NPairHalfRespaNsqNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_respa_nsq_newton.cpp b/src/npair_half_respa_nsq_newton.cpp new file mode 100644 index 0000000000..9aacc702cc --- /dev/null +++ b/src/npair_half_respa_nsq_newton.cpp @@ -0,0 +1,205 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_half_respa_nsq_newton.h" +#include "neighbor.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalfRespaNsqNewton::NPairHalfRespaNsqNewton(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + multiple respa lists + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + pair added to list if atoms i and j are both owned and i < j + if j is ghost only me or other proc adds pair + decision based on itag,jtag tests +------------------------------------------------------------------------- */ + +void NPairHalfRespaNsqNewton::build(NeighList *list) +{ + int i,j,n,itype,jtype,itag,jtag,n_inner,n_middle,bitmask; + int imol,iatom,moltemplate; + tagint tagprev; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + int *neighptr,*neighptr_inner,*neighptr_middle; + + 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 nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *molindex = atom->molindex; + int *molatom = atom->molatom; + Molecule **onemols = atom->avec->onemols; + if (molecular == 2) moltemplate = 1; + else moltemplate = 0; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + ipage_middle = listmiddle->ipage; + } + + int inum = 0; + int which = 0; + int minchange = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + for (i = 0; i < nlocal; i++) { + n = n_inner = 0; + neighptr = ipage->vget(); + neighptr_inner = ipage_inner->vget(); + if (respamiddle) { + n_middle = 0; + neighptr_middle = ipage_middle->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 + + 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 (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 ((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[inum] = 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[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n_inner); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = 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"); + } + + inum++; + } + + list->inum = inum; + listinner->inum = inum; + if (respamiddle) listmiddle->inum = inum; +} diff --git a/src/npair_half_respa_nsq_newton.h b/src/npair_half_respa_nsq_newton.h new file mode 100644 index 0000000000..ad6828b46a --- /dev/null +++ b/src/npair_half_respa_nsq_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/respa/nsq/newton, + NPairHalfRespaNsqNewton, + NP_HALF | NP_RESPA | NP_NSQ | NP_NEWTON | NP_ORTHO) + +#else + +#ifndef LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_H +#define LMP_NPAIR_HALF_RESPA_NSQ_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfRespaNsqNewton : public NPair { + public: + NPairHalfRespaNsqNewton(class LAMMPS *); + ~NPairHalfRespaNsqNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_size_bin_newtoff.cpp b/src/npair_half_size_bin_newtoff.cpp new file mode 100644 index 0000000000..b87bede312 --- /dev/null +++ b/src/npair_half_size_bin_newtoff.cpp @@ -0,0 +1,171 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_bin_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeBinNewtoff::NPairHalfSizeBinNewtoff(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + binned neighbor list construction with partial Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + 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 NPairHalfSizeBinNewtoff::build(NeighList *list) +{ + int i,j,k,m,n,nn,ibin,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + tagint *molecule = atom->molecule; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + ibin = coord2bin(x[i]); + + // 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; + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + + list->inum = inum; +} diff --git a/src/npair_half_size_bin_newtoff.h b/src/npair_half_size_bin_newtoff.h new file mode 100644 index 0000000000..ec3b1af7e9 --- /dev/null +++ b/src/npair_half_size_bin_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/bin/newtoff, + NPairHalfSizeBinNewtoff, + NP_HALF | NP_SIZE | NP_BIN | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_H +#define LMP_NPAIR_HALF_SIZE_BIN_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeBinNewtoff : public NPair { + public: + NPairHalfSizeBinNewtoff(class LAMMPS *); + ~NPairHalfSizeBinNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_size_bin_newton.cpp b/src/npair_half_size_bin_newton.cpp new file mode 100644 index 0000000000..8a32f4e6d6 --- /dev/null +++ b/src/npair_half_size_bin_newton.cpp @@ -0,0 +1,215 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_bin_newton.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeBinNewton::NPairHalfSizeBinNewton(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + binned neighbor list construction with full Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + each owned atom i checks its own bin and other bins in Newton stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +void NPairHalfSizeBinNewton::build(NeighList *list) +{ + int i,j,k,m,n,nn,ibin,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + tagint *molecule = atom->molecule; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // 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; + } + } + + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + + // loop over all atoms in other bins in stencil, store every pair + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + + list->inum = inum; +} diff --git a/src/npair_half_size_bin_newton.h b/src/npair_half_size_bin_newton.h new file mode 100644 index 0000000000..71ec9c5a37 --- /dev/null +++ b/src/npair_half_size_bin_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/bin/newton, + NPairHalfSizeBinNewton, + NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_ORTHO) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_H +#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeBinNewton : public NPair { + public: + NPairHalfSizeBinNewton(class LAMMPS *); + ~NPairHalfSizeBinNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_size_bin_newton_tri.cpp b/src/npair_half_size_bin_newton_tri.cpp new file mode 100644 index 0000000000..620a07159e --- /dev/null +++ b/src/npair_half_size_bin_newton_tri.cpp @@ -0,0 +1,180 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_bin_newton_tri.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeBinNewtonTri::NPairHalfSizeBinNewtonTri(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + binned neighbor list construction with Newton's 3rd law for triclinic + shear history must be accounted for when a neighbor pair is added + each owned atom i checks its own bin and other bins in triclinic stencil + every pair stored exactly once by some processor +------------------------------------------------------------------------- */ + +void NPairHalfSizeBinNewtonTri::build(NeighList *list) +{ + int i,j,k,m,n,nn,ibin,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + tagint *molecule = atom->molecule; + int nlocal = atom->nlocal; + if (includegroup) nlocal = atom->nfirst; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // loop over all atoms in bins in stencil + // pairs for atoms j "below" i are excluded + // below = lower z or (equal z and lower y) or (equal zy and lower x) + // (equal zyx and j <= i) + // latter excludes self-self interaction but allows superposed atoms + + ibin = coord2bin(x[i]); + for (k = 0; k < nstencil; k++) { + for (j = binhead[ibin+stencil[k]]; j >= 0; j = bins[j]) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp) { + if (x[j][0] < xtmp) continue; + if (x[j][0] == xtmp && j <= i) continue; + } + } + + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n++] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + + list->inum = inum; +} diff --git a/src/npair_half_size_bin_newton_tri.h b/src/npair_half_size_bin_newton_tri.h new file mode 100644 index 0000000000..bf956aa7fe --- /dev/null +++ b/src/npair_half_size_bin_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/bin/newton/tri, + NPairHalfSizeBinNewtonTri, + NP_HALF | NP_SIZE | NP_BIN | NP_NEWTON | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_H +#define LMP_NPAIR_HALF_SIZE_BIN_NEWTON_TRI_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeBinNewtonTri : public NPair { + public: + NPairHalfSizeBinNewtonTri(class LAMMPS *); + ~NPairHalfSizeBinNewtonTri() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_size_nsq_newtoff.cpp b/src/npair_half_size_nsq_newtoff.cpp new file mode 100644 index 0000000000..1c2d079893 --- /dev/null +++ b/src/npair_half_size_nsq_newtoff.cpp @@ -0,0 +1,169 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_nsq_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "group.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeNsqNewtoff::NPairHalfSizeNsqNewtoff(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + N^2 / 2 search for neighbor pairs with partial Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + 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 NPairHalfSizeNsqNewtoff::build(NeighList *list) +{ + int i,j,m,n,nn,bitmask,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + tagint *molecule = atom->molecule; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nall; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // loop over remaining atoms, owned and ghost + + for (j = i+1; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + + list->inum = inum; +} diff --git a/src/npair_half_size_nsq_newtoff.h b/src/npair_half_size_nsq_newtoff.h new file mode 100644 index 0000000000..0446208cbb --- /dev/null +++ b/src/npair_half_size_nsq_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/nsq/newtoff, + NPairHalfSizeNsqNewtoff, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_H +#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeNsqNewtoff : public NPair { + public: + NPairHalfSizeNsqNewtoff(class LAMMPS *); + ~NPairHalfSizeNsqNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_half_size_nsq_newton.cpp b/src/npair_half_size_nsq_newton.cpp new file mode 100644 index 0000000000..914a4e7e7d --- /dev/null +++ b/src/npair_half_size_nsq_newton.cpp @@ -0,0 +1,187 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_half_size_nsq_newton.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "group.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairHalfSizeNsqNewton::NPairHalfSizeNsqNewton(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + size particles + N^2 / 2 search for neighbor pairs with full Newton's 3rd law + shear history must be accounted for when a neighbor pair is added + pair added to list if atoms i and j are both owned and i < j + if j is ghost only me or other proc adds pair + decision based on itag,jtag tests +------------------------------------------------------------------------- */ + +void NPairHalfSizeNsqNewton::build(NeighList *list) +{ + int i,j,m,n,nn,itag,jtag,bitmask,dnum,dnumbytes; + double xtmp,ytmp,ztmp,delx,dely,delz,rsq; + double radi,radsum,cutsq; + int *neighptr,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + double **x = atom->x; + double *radius = atom->radius; + tagint *tag = atom->tag; + int *type = atom->type; + int *mask = atom->mask; + tagint *molecule = atom->molecule; + int nlocal = atom->nlocal; + int nall = nlocal + atom->nghost; + if (includegroup) { + nlocal = atom->nfirst; + bitmask = group->bitmask[includegroup]; + } + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nall; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + for (i = 0; i < nlocal; i++) { + n = 0; + neighptr = ipage->vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + itag = tag[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + radi = radius[i]; + + // loop over remaining atoms, owned and ghost + + 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 (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; + } + } + } + + if (exclude && exclusion(i,j,type[i],type[j],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; + radsum = radi + radius[j]; + cutsq = (radsum+skin) * (radsum+skin); + + if (rsq <= cutsq) { + neighptr[n] = j; + + if (fix_history) { + if (rsq < radsum*radsum) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == tag[j]) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + + list->inum = inum; +} diff --git a/src/npair_half_size_nsq_newton.h b/src/npair_half_size_nsq_newton.h new file mode 100644 index 0000000000..3550d6c7f5 --- /dev/null +++ b/src/npair_half_size_nsq_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(half/size/nsq/newton, + NPairHalfSizeNsqNewton, + NP_HALF | NP_SIZE | NP_NSQ | NP_NEWTON | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_H +#define LMP_NPAIR_HALF_SIZE_NSQ_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalfSizeNsqNewton : public NPair { + public: + NPairHalfSizeNsqNewton(class LAMMPS *); + ~NPairHalfSizeNsqNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_halffull_newtoff.cpp b/src/npair_halffull_newtoff.cpp new file mode 100644 index 0000000000..bd7cc4dd59 --- /dev/null +++ b/src/npair_halffull_newtoff.cpp @@ -0,0 +1,82 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_halffull_newtoff.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalffullNewtoff::NPairHalffullNewtoff(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build half list from full list + 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) + works if full list is a skip list +------------------------------------------------------------------------- */ + +void NPairHalffullNewtoff::build(NeighList *list) +{ + int i,j,ii,jj,n,jnum,joriginal; + int *neighptr,*jlist; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_full = list->listfull->ilist; + int *numneigh_full = list->listfull->numneigh; + int **firstneigh_full = list->listfull->firstneigh; + int inum_full = list->listfull->inum; + + int inum = 0; + ipage->reset(); + + // loop over atoms in full list + + for (ii = 0; ii < inum_full; ii++) { + n = 0; + neighptr = ipage->vget(); + + // loop over parent full list + + i = ilist_full[ii]; + jlist = firstneigh_full[i]; + jnum = numneigh_full[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (j > i) neighptr[n++] = joriginal; + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_halffull_newtoff.h b/src/npair_halffull_newtoff.h new file mode 100644 index 0000000000..20ceeabaad --- /dev/null +++ b/src/npair_halffull_newtoff.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(halffull/newtoff, + NPairHalffullNewtoff, + NP_HALFFULL | NP_NSQ | NP_BIN | NP_MULTI | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALFFULL_NEWTOFF_H +#define LMP_NPAIR_HALFFULL_NEWTOFF_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalffullNewtoff : public NPair { + public: + NPairHalffullNewtoff(class LAMMPS *); + ~NPairHalffullNewtoff() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_halffull_newton.cpp b/src/npair_halffull_newton.cpp new file mode 100644 index 0000000000..371bbd33a8 --- /dev/null +++ b/src/npair_halffull_newton.cpp @@ -0,0 +1,99 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_halffull_newton.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; + +/* ---------------------------------------------------------------------- */ + +NPairHalffullNewton::NPairHalffullNewton(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + 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 +------------------------------------------------------------------------- */ + +void NPairHalffullNewton::build(NeighList *list) +{ + int i,j,ii,jj,n,jnum,joriginal; + int *neighptr,*jlist; + double xtmp,ytmp,ztmp; + + double **x = atom->x; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_full = list->listfull->ilist; + int *numneigh_full = list->listfull->numneigh; + int **firstneigh_full = list->listfull->firstneigh; + int inum_full = list->listfull->inum; + + int inum = 0; + ipage->reset(); + + // loop over parent full list + + for (ii = 0; ii < inum_full; ii++) { + n = 0; + neighptr = ipage->vget(); + + i = ilist_full[ii]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + + // loop over full neighbor list + + jlist = firstneigh_full[i]; + jnum = numneigh_full[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (j < nlocal) { + if (i > j) 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; + } + } + neighptr[n++] = joriginal; + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; +} diff --git a/src/npair_halffull_newton.h b/src/npair_halffull_newton.h new file mode 100644 index 0000000000..0f0aee58dc --- /dev/null +++ b/src/npair_halffull_newton.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(halffull/newton, + NPairHalffullNewton, + NP_HALFFULL | NP_NSQ | NP_BIN | NP_MULTI | NP_NEWTON | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_HALFFULL_NEWTON_H +#define LMP_NPAIR_HALFFULL_NEWTON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairHalffullNewton : public NPair { + public: + NPairHalffullNewton(class LAMMPS *); + ~NPairHalffullNewton() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_skip.cpp b/src/npair_skip.cpp new file mode 100644 index 0000000000..3048460859 --- /dev/null +++ b/src/npair_skip.cpp @@ -0,0 +1,103 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_skip.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; + +/* ---------------------------------------------------------------------- */ + +NPairSkip::NPairSkip(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + this is for half and full lists + if ghost, also store neighbors of ghost atoms & set inum,gnum correctly +------------------------------------------------------------------------- */ + +void NPairSkip::build(NeighList *list) +{ + int i,j,ii,jj,n,itype,jnum,joriginal; + int *neighptr,*jlist; + + int *type = atom->type; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int num_skip = list->listskip->inum; + if (list->ghost) num_skip += list->listskip->gnum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + int inum = 0; + ipage->reset(); + + // loop over atoms in other list + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (ii = 0; ii < num_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + n = 0; + neighptr = ipage->vget(); + + // loop over parent non-skip list + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr[n++] = joriginal; + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + list->inum = inum; + if (list->ghost) { + int num = 0; + for (i = 0; i < inum; i++) + if (ilist[i] < nlocal) num++; + else break; + list->inum = num; + list->gnum = inum - num; + } +} diff --git a/src/npair_skip.h b/src/npair_skip.h new file mode 100644 index 0000000000..872fd9cb58 --- /dev/null +++ b/src/npair_skip.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(skip, + NPairSkip, + NP_SKIP | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_SKIP_H +#define LMP_NPAIR_SKIP_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkip : public NPair { + public: + NPairSkip(class LAMMPS *); + ~NPairSkip() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_skip_respa.cpp b/src/npair_skip_respa.cpp new file mode 100644 index 0000000000..31420b32d1 --- /dev/null +++ b/src/npair_skip_respa.cpp @@ -0,0 +1,169 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "npair_skip_respa.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; + +/* ---------------------------------------------------------------------- */ + +NPairSkipRespa::NPairSkipRespa(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + this is for respa lists, copy the inner/middle values from parent +------------------------------------------------------------------------- */ + +void NPairSkipRespa::build(NeighList *list) +{ + int i,j,ii,jj,n,itype,jnum,joriginal,n_inner,n_middle; + int *neighptr,*jlist,*neighptr_inner,*neighptr_middle; + + int *type = atom->type; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int inum_skip = list->listskip->inum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage *ipage_inner = listinner->ipage; + + int *numneigh_inner_skip = list->listskip->listinner->numneigh; + int **firstneigh_inner_skip = list->listskip->listinner->firstneigh; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage *ipage_middle; + int *numneigh_middle_skip,**firstneigh_middle_skip; + int respamiddle = list->respamiddle; + if (respamiddle) { + listmiddle = list->listmiddle; + ilist_middle = listmiddle->ilist; + numneigh_middle = listmiddle->numneigh; + firstneigh_middle = listmiddle->firstneigh; + ipage_middle = listmiddle->ipage; + numneigh_middle_skip = list->listskip->listmiddle->numneigh; + firstneigh_middle_skip = list->listskip->listmiddle->firstneigh; + } + + int inum = 0; + ipage->reset(); + ipage_inner->reset(); + if (respamiddle) ipage_middle->reset(); + + // loop over atoms in other list + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + n = n_inner = 0; + neighptr = ipage->vget(); + neighptr_inner = ipage_inner->vget(); + if (respamiddle) { + n_middle = 0; + neighptr_middle = ipage_middle->vget(); + } + + // loop over parent outer rRESPA list + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr[n++] = joriginal; + } + + // loop over parent inner rRESPA list + + jlist = firstneigh_inner_skip[i]; + jnum = numneigh_inner_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr_inner[n_inner++] = joriginal; + } + + // loop over parent middle rRESPA list + + if (respamiddle) { + jlist = firstneigh_middle_skip[i]; + jnum = numneigh_middle_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr_middle[n_middle++] = joriginal; + } + } + + ilist[inum] = 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[inum] = i; + firstneigh_inner[i] = neighptr_inner; + numneigh_inner[i] = n_inner; + ipage_inner->vgot(n); + if (ipage_inner->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (respamiddle) { + ilist_middle[inum] = i; + firstneigh_middle[i] = neighptr_middle; + numneigh_middle[i] = n_middle; + ipage_middle->vgot(n); + if (ipage_middle->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + } + + inum++; + } + + list->inum = inum; + listinner->inum = inum; + if (respamiddle) listmiddle->inum = inum; +} diff --git a/src/npair_skip_respa.h b/src/npair_skip_respa.h new file mode 100644 index 0000000000..62077f85df --- /dev/null +++ b/src/npair_skip_respa.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(skip/half/respa, + NPairSkipRespa, + NP_SKIP | NP_RESPA | NP_HALF | NP_FULL | + NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_SKIP_RESPA_H +#define LMP_NPAIR_SKIP_RESPA_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkipRespa : public NPair { + public: + NPairSkipRespa(class LAMMPS *); + ~NPairSkipRespa() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_skip_size.cpp b/src/npair_skip_size.cpp new file mode 100644 index 0000000000..c69b16d1df --- /dev/null +++ b/src/npair_skip_size.cpp @@ -0,0 +1,161 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_skip_size.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairSkipSize::NPairSkipSize(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + if list requests it, preserve shear history via fix shear/history +------------------------------------------------------------------------- */ + +void NPairSkipSize::build(NeighList *list) +{ + int i,j,ii,jj,m,n,nn,itype,jnum,joriginal,dnum,dnumbytes; + tagint jtag; + int *neighptr,*jlist,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + tagint *tag = atom->tag; + int *type = atom->type; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int inum_skip = list->listskip->inum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + // loop over atoms in other list + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + n = 0; + neighptr = ipage->vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + // loop over parent non-skip size list and optionally its history info + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + neighptr[n] = joriginal; + + // no numeric test for current touch + // just use FSH partner list to infer it + // would require distance calculation for spheres + // more complex calculation for surfs + + if (fix_history) { + jtag = tag[j]; + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == jtag) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + + list->inum = inum; +} diff --git a/src/npair_skip_size.h b/src/npair_skip_size.h new file mode 100644 index 0000000000..9573396641 --- /dev/null +++ b/src/npair_skip_size.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(skip/half/size, + NPairSkipSize, + NP_SKIP | NP_SIZE | NP_HALF | NP_FULL | NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_SKIP_SIZE_H +#define LMP_NPAIR_SKIP_SIZE_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkipSize : public NPair { + public: + NPairSkipSize(class LAMMPS *); + ~NPairSkipSize() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_skip_size_off2on.cpp b/src/npair_skip_size_off2on.cpp new file mode 100644 index 0000000000..bd509327f1 --- /dev/null +++ b/src/npair_skip_size_off2on.cpp @@ -0,0 +1,168 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_skip_size_off2on.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairSkipSizeOff2on::NPairSkipSizeOff2on(LAMMPS *lmp) : NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + parent non-skip list used newton off, this skip list is newton on + if list requests it, preserve shear history via fix shear/history +------------------------------------------------------------------------- */ + +void NPairSkipSizeOff2on::build(NeighList *list) +{ + int i,j,ii,jj,m,n,nn,itype,jnum,joriginal,dnum,dnumbytes; + tagint itag,jtag; + int *neighptr,*jlist,*touchptr; + double *shearptr; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + tagint *tag = atom->tag; + int *type = atom->type; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int inum_skip = list->listskip->inum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + // loop over atoms in other list + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + itag = tag[i]; + + n = 0; + neighptr = ipage->vget(); + if (fix_history) { + nn = 0; + touchptr = ipage_touch->vget(); + shearptr = dpage_shear->vget(); + } + + // loop over parent non-skip size list and optionally its history info + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + + // only keep I,J when J = ghost if Itag < Jtag + + jtag = tag[j]; + if (j >= nlocal && jtag < itag) continue; + + neighptr[n] = joriginal; + + // no numeric test for current touch + // just use FSH partner list to infer it + // would require distance calculation for spheres + // more complex calculation for surfs + + if (fix_history) { + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == jtag) break; + if (m < npartner[i]) { + touchptr[n] = 1; + memcpy(&shearptr[nn],&shearpartner[i][dnum*m],dnumbytes); + nn += dnum; + } else { + touchptr[n] = 0; + memcpy(&shearptr[nn],zeroes,dnumbytes); + nn += dnum; + } + } + + n++; + } + + ilist[inum++] = i; + firstneigh[i] = neighptr; + numneigh[i] = n; + ipage->vgot(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + + if (fix_history) { + firsttouch[i] = touchptr; + firstshear[i] = shearptr; + ipage_touch->vgot(n); + dpage_shear->vgot(nn); + } + } + + list->inum = inum; +} diff --git a/src/npair_skip_size_off2on.h b/src/npair_skip_size_off2on.h new file mode 100644 index 0000000000..4b4e9a9c29 --- /dev/null +++ b/src/npair_skip_size_off2on.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(skip/size/off2on, + NPairSkipSizeOff2on, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | + NP_NEWTON | NP_NEWTOFF | NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_SKIP_SIZE_OFF2ON_H +#define LMP_NPAIR_SKIP_SIZE_OFF2ON_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkipSizeOff2on : public NPair { + public: + NPairSkipSizeOff2on(class LAMMPS *); + ~NPairSkipSizeOff2on() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/npair_skip_size_off2on_oneside.cpp b/src/npair_skip_size_off2on_oneside.cpp new file mode 100644 index 0000000000..12123741d0 --- /dev/null +++ b/src/npair_skip_size_off2on_oneside.cpp @@ -0,0 +1,223 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "npair_skip_size_off2on_oneside.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" +#include "atom_vec.h" +#include "molecule.h" +#include "domain.h" +#include "fix_shear_history.h" +#include "my_page.h" +#include "error.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NPairSkipSizeOff2onOneside::NPairSkipSizeOff2onOneside(LAMMPS *lmp) : + NPair(lmp) {} + +/* ---------------------------------------------------------------------- + build skip list for subset of types from parent list + iskip and ijskip flag which atom types and type pairs to skip + parent non-skip list used newton off and was not onesided, + this skip list is newton on and onesided + if list requests it, preserve shear history via fix shear/history +------------------------------------------------------------------------- */ + +void NPairSkipSizeOff2onOneside::build(NeighList *list) +{ + int i,j,ii,jj,m,n,nn,itype,jnum,joriginal,flip,dnum,dnumbytes,tmp; + tagint jtag; + int *surf,*jlist; + + int *npartner; + tagint **partner; + double **shearpartner; + int **firsttouch; + double **firstshear; + MyPage *ipage_touch; + MyPage *dpage_shear; + NeighList *listgranhistory; + + tagint *tag = atom->tag; + int *type = atom->type; + int nlocal = atom->nlocal; + + int *ilist = list->ilist; + int *numneigh = list->numneigh; + int **firstneigh = list->firstneigh; + MyPage *ipage = list->ipage; + + int *ilist_skip = list->listskip->ilist; + int *numneigh_skip = list->listskip->numneigh; + int **firstneigh_skip = list->listskip->firstneigh; + int inum_skip = list->listskip->inum; + + int *iskip = list->iskip; + int **ijskip = list->ijskip; + + if (domain->dimension == 2) surf = atom->line; + else surf = atom->tri; + + FixShearHistory *fix_history = list->fix_history; + if (fix_history) { + fix_history->nlocal_neigh = nlocal; + fix_history->nall_neigh = nlocal + atom->nghost; + npartner = fix_history->npartner; + partner = fix_history->partner; + shearpartner = fix_history->shearpartner; + listgranhistory = list->listgranhistory; + firsttouch = listgranhistory->firstneigh; + firstshear = listgranhistory->firstdouble; + ipage_touch = listgranhistory->ipage; + dpage_shear = listgranhistory->dpage; + dnum = listgranhistory->dnum; + dnumbytes = dnum * sizeof(double); + } + + int inum = 0; + ipage->reset(); + if (fix_history) { + ipage_touch->reset(); + dpage_shear->reset(); + } + + // two loops over parent list required, one to count, one to store + // because onesided constraint means pair I,J may be stored with I or J + // so don't know in advance how much space to alloc for each atom's neighs + + // first loop over atoms in other list to count neighbors + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (i = 0; i < nlocal; i++) numneigh[i] = 0; + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + n = 0; + + // loop over parent non-skip size list + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + + // flip I,J if necessary to satisfy onesided constraint + // do not keep if I is now ghost + + if (surf[i] >= 0) { + if (j >= nlocal) continue; + tmp = i; + i = j; + j = tmp; + flip = 1; + } else flip = 0; + + numneigh[i]++; + if (flip) i = j; + } + } + + // allocate all per-atom neigh list chunks, including history + + for (i = 0; i < nlocal; i++) { + if (numneigh[i] == 0) continue; + n = numneigh[i]; + firstneigh[i] = ipage->get(n); + if (ipage->status()) + error->one(FLERR,"Neighbor list overflow, boost neigh_modify one"); + if (fix_history) { + firsttouch[i] = ipage_touch->get(n); + firstshear[i] = dpage_shear->get(dnum*n); + } + } + + // second loop over atoms in other list to store neighbors + // skip I atom entirely if iskip is set for type[I] + // skip I,J pair if ijskip is set for type[I],type[J] + + for (i = 0; i < nlocal; i++) numneigh[i] = 0; + + for (ii = 0; ii < inum_skip; ii++) { + i = ilist_skip[ii]; + itype = type[i]; + if (iskip[itype]) continue; + + // loop over parent non-skip size list and optionally its history info + + jlist = firstneigh_skip[i]; + jnum = numneigh_skip[i]; + + for (jj = 0; jj < jnum; jj++) { + joriginal = jlist[jj]; + j = joriginal & NEIGHMASK; + if (ijskip[itype][type[j]]) continue; + + // flip I,J if necessary to satisfy onesided constraint + // do not keep if I is now ghost + + if (surf[i] >= 0) { + if (j >= nlocal) continue; + tmp = i; + i = j; + j = tmp; + flip = 1; + } else flip = 0; + + // store j in neigh list, not joriginal, like other neigh methods + // OK, b/c there is no special list flagging for surfs + + firstneigh[i][numneigh[i]] = j; + + // no numeric test for current touch + // just use FSH partner list to infer it + // would require complex calculation for surfs + + if (fix_history) { + jtag = tag[j]; + n = numneigh[i]; + nn = dnum*n; + for (m = 0; m < npartner[i]; m++) + if (partner[i][m] == jtag) break; + if (m < npartner[i]) { + firsttouch[i][n] = 1; + memcpy(&firstshear[i][nn],&shearpartner[i][dnum*m],dnumbytes); + } else { + firsttouch[i][n] = 0; + memcpy(&firstshear[i][nn],zeroes,dnumbytes); + } + } + + numneigh[i]++; + if (flip) i = j; + } + + // only add atom I to ilist if it has neighbors + // fix shear/history allows for this in pre_exchange_onesided() + + if (numneigh[i]) ilist[inum++] = i; + } + + list->inum = inum; +} diff --git a/src/npair_skip_size_off2on_oneside.h b/src/npair_skip_size_off2on_oneside.h new file mode 100644 index 0000000000..9f3c06e7bc --- /dev/null +++ b/src/npair_skip_size_off2on_oneside.h @@ -0,0 +1,45 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NPAIR_CLASS + +NPairStyle(skip/size/off2on/oneside, + NPairSkipSizeOff2onOneside, + NP_SKIP | NP_SIZE | NP_OFF2ON | NP_ONESIDE | NP_HALF | + NP_NSQ | NP_BIN | NP_MULTI | NP_NEWTON | NP_NEWTOFF | + NP_ORTHO | NP_TRI) + +#else + +#ifndef LMP_NPAIR_SKIP_SIZE_OFF2ON_ONESIDE_H +#define LMP_NPAIR_SKIP_SIZE_OFF2ON_ONESIDE_H + +#include "npair.h" + +namespace LAMMPS_NS { + +class NPairSkipSizeOff2onOneside : public NPair { + public: + NPairSkipSizeOff2onOneside(class LAMMPS *); + ~NPairSkipSizeOff2onOneside() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil.cpp b/src/nstencil.cpp new file mode 100644 index 0000000000..68d5f80412 --- /dev/null +++ b/src/nstencil.cpp @@ -0,0 +1,230 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil.h" +#include "neighbor.h" +#include "nbin.h" +#include "atom.h" +#include "update.h" +#include "domain.h" +#include "memory.h" + +using namespace LAMMPS_NS; + +enum{NSQ,BIN,MULTI}; // also in Neighbor + +/* ---------------------------------------------------------------------- + NStencil classes + each has method to create a stencil = list of bin offsets + invoked each time simulation box size/shape changes + since induces change in bins + stencil = bins whose closest corner to central bin is within cutoff + sx,sy,sz = bin bounds = furthest the stencil could possibly extend + calculated below in create_setup() + 3d creates xyz stencil, 2d creates xy stencil + for half list with newton off: + stencil is all surrounding bins including self + regardless of triclinic + for half list with newton on: + stencil is bins to the "upper right" of central bin + stencil does not include self + no versions that allow ghost on (no callers need it?) + for half list with newton on and triclinic: + stencil is all bins in z-plane of self and above, but not below + in 2d is all bins in y-plane of self and above, but not below + stencil includes self + no versions that allow ghost on (no callers need it?) + for full list: + stencil is all surrounding bins including self + regardless of newton on/off or triclinic + for multi: + create one stencil for each atom type + stencil follows same rules for half/full, newton on/off, triclinic + cutoff is not cutneighmaxsq, but max cutoff for that atom type + no versions that allow ghost on (any need for it?) +------------------------------------------------------------------------- */ + +NStencil::NStencil(LAMMPS *lmp) : Pointers(lmp) +{ + last_create = last_stencil_memory = -1; + last_copy_bin = -1; + + xyzflag = 0; + + maxstencil = maxstencil_multi = 0; + stencil = NULL; + stencilxyz = NULL; + nstencil_multi = NULL; + stencil_multi = NULL; + distsq_multi = NULL; + + dimension = domain->dimension; +} + +/* ---------------------------------------------------------------------- */ + +NStencil::~NStencil() +{ + memory->destroy(stencil); + memory->destroy(stencilxyz); + + if (!stencil_multi) return; + + int n = atom->ntypes; + for (int i = 1; i <= n; i++) { + memory->destroy(stencil_multi[i]); + memory->destroy(distsq_multi[i]); + } + delete [] nstencil_multi; + delete [] stencil_multi; + delete [] distsq_multi; +} + +/* ---------------------------------------------------------------------- + copy needed info from Neighbor class to this stencil class +------------------------------------------------------------------------- */ + +void NStencil::copy_neighbor_info() +{ + neighstyle = neighbor->style; + cutneighmax = neighbor->cutneighmax; + cutneighmaxsq = neighbor->cutneighmaxsq; + cuttypesq = neighbor->cuttypesq; +} + +/* ---------------------------------------------------------------------- + copy needed info from NBin class to this stencil class +------------------------------------------------------------------------- */ + +void NStencil::copy_bin_info() +{ + mbinx = nb->mbinx; + mbiny = nb->mbiny; + mbinz = nb->mbinz; + binsizex = nb->binsizex; + binsizey = nb->binsizey; + binsizez = nb->binsizez; + bininvx = nb->bininvx; + bininvy = nb->bininvy; + bininvz = nb->bininvz; +} + +/* ---------------------------------------------------------------------- + insure NBin data is current + insure stencils are allocated large enough +------------------------------------------------------------------------- */ + +void NStencil::create_setup() +{ + if (nb && last_copy_bin < nb->last_setup) { + copy_bin_info(); + last_copy_bin = update->ntimestep; + } + + // sx,sy,sz = max range of stencil in each dim + // smax = max possible size of entire 3d stencil + // stencil will be empty if cutneighmax = 0.0 + + sx = static_cast (cutneighmax*bininvx); + if (sx*binsizex < cutneighmax) sx++; + sy = static_cast (cutneighmax*bininvy); + if (sy*binsizey < cutneighmax) sy++; + sz = static_cast (cutneighmax*bininvz); + if (sz*binsizez < cutneighmax) sz++; + if (dimension == 2) sz = 0; + + int smax = (2*sx+1) * (2*sy+1) * (2*sz+1); + + // reallocate stencil structs if necessary + // for BIN and MULTI styles + + if (neighstyle == BIN) { + if (smax > maxstencil) { + maxstencil = smax; + memory->destroy(stencil); + memory->create(stencil,maxstencil,"neighstencil:stencil"); + if (xyzflag) { + memory->destroy(stencilxyz); + memory->create(stencilxyz,maxstencil,3,"neighstencil:stencilxyz"); + } + last_stencil_memory = update->ntimestep; + } + + } else { + int i; + int n = atom->ntypes; + if (maxstencil_multi == 0) { + nstencil_multi = new int[n+1]; + stencil_multi = new int*[n+1]; + distsq_multi = new double*[n+1]; + for (i = 1; i <= n; i++) { + nstencil_multi[i] = 0; + stencil_multi[i] = NULL; + distsq_multi[i] = NULL; + } + last_stencil_memory = update->ntimestep; + } + if (smax > maxstencil_multi) { + maxstencil_multi = smax; + for (i = 1; i <= n; i++) { + memory->destroy(stencil_multi[i]); + memory->destroy(distsq_multi[i]); + memory->create(stencil_multi[i],maxstencil_multi, + "neighstencil:stencil_multi"); + memory->create(distsq_multi[i],maxstencil_multi, + "neighstencil:distsq_multi"); + last_stencil_memory = update->ntimestep; + } + } + } + + last_create = update->ntimestep; +} + +/* ---------------------------------------------------------------------- + compute closest distance between central bin (0,0,0) and bin (i,j,k) +------------------------------------------------------------------------- */ + +double NStencil::bin_distance(int i, int j, int k) +{ + double delx,dely,delz; + + if (i > 0) delx = (i-1)*binsizex; + else if (i == 0) delx = 0.0; + else delx = (i+1)*binsizex; + + if (j > 0) dely = (j-1)*binsizey; + else if (j == 0) dely = 0.0; + else dely = (j+1)*binsizey; + + if (k > 0) delz = (k-1)*binsizez; + else if (k == 0) delz = 0.0; + else delz = (k+1)*binsizez; + + return (delx*delx + dely*dely + delz*delz); +} + +/* ---------------------------------------------------------------------- */ + +bigint NStencil::memory_usage() +{ + bigint bytes = 0; + if (neighstyle == BIN) { + bytes += memory->usage(stencil,maxstencil); + bytes += memory->usage(stencilxyz,maxstencil,3); + } else if (neighstyle == MULTI) { + bytes += atom->ntypes*maxstencil_multi * sizeof(int); + bytes += atom->ntypes*maxstencil_multi * sizeof(double); + } + return bytes; +} diff --git a/src/nstencil.h b/src/nstencil.h new file mode 100644 index 0000000000..8672584a19 --- /dev/null +++ b/src/nstencil.h @@ -0,0 +1,83 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_NSTENCIL_H +#define LMP_NSTENCIL_H + +#include "pointers.h" + +namespace LAMMPS_NS { + +class NStencil : protected Pointers { + public: + int istyle; // 1-N index into binnames + class NBin *nb; // ptr to NBin instance I depend on + + bigint last_create; // timesteps for last operations performed + bigint last_stencil_memory; + bigint last_copy_bin; + + int nstencil; // # of bins in stencil + int *stencil; // list of bin offsets + int **stencilxyz; // bin offsets in xyz dims + int *nstencil_multi; // # bins in each type-based multi stencil + int **stencil_multi; // list of bin offsets in each stencil + double **distsq_multi; // sq distances to bins in each stencil + + NStencil(class LAMMPS *); + virtual ~NStencil(); + void copy_neighbor_info(); + virtual void create_setup(); + bigint memory_usage(); + + virtual void create() = 0; + + inline int get_maxstencil() {return maxstencil;} + + protected: + + // data from Neighbor class + + int neighstyle; + double cutneighmax; + double cutneighmaxsq; + double *cuttypesq; + + // data from NBin class + + int mbinx,mbiny,mbinz; + double binsizex,binsizey,binsizez; + double bininvx,bininvy,bininvz; + + // data common to all NStencil variants + + int xyzflag; // 1 if stencilxyz is allocated + int maxstencil; // max size of stencil + int maxstencil_multi; // max sizes of stencils + int sx,sy,sz; // extent of stencil in each dim + + int dimension; + + // methods for all NStencil variants + + void copy_bin_info(); // copy info from NBin class + double bin_distance(int, int, int); // distance between bin corners +}; + +} + +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_full_bin_2d.cpp b/src/nstencil_full_bin_2d.cpp new file mode 100644 index 0000000000..1f2b666dfb --- /dev/null +++ b/src/nstencil_full_bin_2d.cpp @@ -0,0 +1,38 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_full_bin_2d.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilFullBin2d::NStencilFullBin2d(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilFullBin2d::create() +{ + int i,j; + + nstencil = 0; + + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[nstencil++] = j*mbinx + i; +} diff --git a/src/nstencil_full_bin_2d.h b/src/nstencil_full_bin_2d.h new file mode 100644 index 0000000000..18f848f275 --- /dev/null +++ b/src/nstencil_full_bin_2d.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(full/bin/2d, + NStencilFullBin2d, + NS_FULL | NS_BIN | NS_2D | + NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_FULL_BIN_2D_H +#define LMP_NSTENCIL_FULL_BIN_2D_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilFullBin2d : public NStencil { + public: + NStencilFullBin2d(class LAMMPS *); + ~NStencilFullBin2d() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_full_bin_3d.cpp b/src/nstencil_full_bin_3d.cpp new file mode 100644 index 0000000000..b6a2198132 --- /dev/null +++ b/src/nstencil_full_bin_3d.cpp @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_full_bin_3d.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilFullBin3d::NStencilFullBin3d(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilFullBin3d::create() +{ + int i,j,k; + + 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) + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; +} diff --git a/src/nstencil_full_bin_3d.h b/src/nstencil_full_bin_3d.h new file mode 100644 index 0000000000..d9acc9c535 --- /dev/null +++ b/src/nstencil_full_bin_3d.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(full/bin/3d, + NStencilFullBin3d, + NS_FULL | NS_BIN | NS_3D | + NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_FULL_BIN_3D_H +#define LMP_NSTENCIL_FULL_BIN_3D_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilFullBin3d : public NStencil { + public: + NStencilFullBin3d(class LAMMPS *); + ~NStencilFullBin3d() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_full_ghost_bin_2d.cpp b/src/nstencil_full_ghost_bin_2d.cpp new file mode 100644 index 0000000000..bbbf1a4466 --- /dev/null +++ b/src/nstencil_full_ghost_bin_2d.cpp @@ -0,0 +1,45 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_full_ghost_bin_2d.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilFullGhostBin2d::NStencilFullGhostBin2d(LAMMPS *lmp) : NStencil(lmp) +{ + xyzflag = 1; +} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilFullGhostBin2d::create() +{ + int i,j; + + nstencil = 0; + + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) { + stencilxyz[nstencil][0] = i; + stencilxyz[nstencil][1] = j; + stencilxyz[nstencil][2] = 0; + stencil[nstencil++] = j*mbinx + i; + } +} diff --git a/src/nstencil_full_ghost_bin_2d.h b/src/nstencil_full_ghost_bin_2d.h new file mode 100644 index 0000000000..af47913e7f --- /dev/null +++ b/src/nstencil_full_ghost_bin_2d.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(full/ghost/bin/2d, + NStencilFullGhostBin2d, + NS_FULL | NS_GHOST | NS_BIN | NS_2D | + NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_FULL_GHOST_BIN_2D_H +#define LMP_NSTENCIL_FULL_GHOST_BIN_2D_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilFullGhostBin2d : public NStencil { + public: + NStencilFullGhostBin2d(class LAMMPS *); + ~NStencilFullGhostBin2d() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_full_ghost_bin_3d.cpp b/src/nstencil_full_ghost_bin_3d.cpp new file mode 100644 index 0000000000..e9abca2174 --- /dev/null +++ b/src/nstencil_full_ghost_bin_3d.cpp @@ -0,0 +1,46 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_full_ghost_bin_3d.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilFullGhostBin3d::NStencilFullGhostBin3d(LAMMPS *lmp) : NStencil(lmp) +{ + xyzflag = 1; +} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilFullGhostBin3d::create() +{ + int i,j,k; + + 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) { + stencilxyz[nstencil][0] = i; + stencilxyz[nstencil][1] = j; + stencilxyz[nstencil][2] = k; + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + } +} diff --git a/src/nstencil_full_ghost_bin_3d.h b/src/nstencil_full_ghost_bin_3d.h new file mode 100644 index 0000000000..beca6573de --- /dev/null +++ b/src/nstencil_full_ghost_bin_3d.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(full/ghost/bin/3d, + NStencilFullGhostBin3d, + NS_FULL | NS_GHOST | NS_BIN | NS_3D | + NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_FULL_GHOST_BIN_3D_H +#define LMP_NSTENCIL_FULL_GHOST_BIN_3D_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilFullGhostBin3d : public NStencil { + public: + NStencilFullGhostBin3d(class LAMMPS *); + ~NStencilFullGhostBin3d() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_full_multi_2d.cpp b/src/nstencil_full_multi_2d.cpp new file mode 100644 index 0000000000..ed2ffe11dc --- /dev/null +++ b/src/nstencil_full_multi_2d.cpp @@ -0,0 +1,52 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_full_multi_2d.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilFullMulti2d::NStencilFullMulti2d(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilFullMulti2d::create() +{ + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_full_multi_2d.h b/src/nstencil_full_multi_2d.h new file mode 100644 index 0000000000..8154144eda --- /dev/null +++ b/src/nstencil_full_multi_2d.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(full/multi/2d, + NStencilFullMulti2d, + NS_FULL | NS_MULTI | NS_2D | + NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_FULL_MULTI_2D_H +#define LMP_NSTENCIL_FULL_MULTI_2D_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilFullMulti2d : public NStencil { + public: + NStencilFullMulti2d(class LAMMPS *); + ~NStencilFullMulti2d() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_full_multi_3d.cpp b/src/nstencil_full_multi_3d.cpp new file mode 100644 index 0000000000..c171bfadc5 --- /dev/null +++ b/src/nstencil_full_multi_3d.cpp @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_full_multi_3d.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilFullMulti3d::NStencilFullMulti3d(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilFullMulti3d::create() +{ + int i,j,k,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (k = -sz; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,k); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = k*mbiny*mbinx + j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_full_multi_3d.h b/src/nstencil_full_multi_3d.h new file mode 100644 index 0000000000..9e3696f5d2 --- /dev/null +++ b/src/nstencil_full_multi_3d.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(full/multi/3d, + NStencilFullMulti3d, + NS_FULL | NS_MULTI | NS_3D | + NS_NEWTON | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_FULL_MULTI_3D_H +#define LMP_NSTENCIL_FULL_MULTI_3D_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilFullMulti3d : public NStencil { + public: + NStencilFullMulti3d(class LAMMPS *); + ~NStencilFullMulti3d() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_bin_2d_newtoff.cpp b/src/nstencil_half_bin_2d_newtoff.cpp new file mode 100644 index 0000000000..be5bc81dbf --- /dev/null +++ b/src/nstencil_half_bin_2d_newtoff.cpp @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_2d_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin2dNewtoff::NStencilHalfBin2dNewtoff(LAMMPS *lmp) : + NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfBin2dNewtoff::create() +{ + int i,j; + + nstencil = 0; + + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[nstencil++] = j*mbinx + i; +} diff --git a/src/nstencil_half_bin_2d_newtoff.h b/src/nstencil_half_bin_2d_newtoff.h new file mode 100644 index 0000000000..7a350df1bc --- /dev/null +++ b/src/nstencil_half_bin_2d_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/2d/newtoff, + NStencilHalfBin2dNewtoff, + NS_HALF | NS_BIN | NS_2D | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_2D_NEWTOFF_H +#define LMP_NSTENCIL_HALF_BIN_2D_NEWTOFF_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin2dNewtoff : public NStencil { + public: + NStencilHalfBin2dNewtoff(class LAMMPS *); + ~NStencilHalfBin2dNewtoff() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_bin_2d_newton.cpp b/src/nstencil_half_bin_2d_newton.cpp new file mode 100644 index 0000000000..9479bbf0c8 --- /dev/null +++ b/src/nstencil_half_bin_2d_newton.cpp @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_2d_newton.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin2dNewton::NStencilHalfBin2dNewton(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfBin2dNewton::create() +{ + int i,j; + + nstencil = 0; + + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (j > 0 || (j == 0 && i > 0)) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[nstencil++] = j*mbinx + i; +} diff --git a/src/nstencil_half_bin_2d_newton.h b/src/nstencil_half_bin_2d_newton.h new file mode 100644 index 0000000000..64bbfc5fe4 --- /dev/null +++ b/src/nstencil_half_bin_2d_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/2d/newton, + NStencilHalfBin2dNewton, + NS_HALF | NS_BIN | NS_2D | NS_NEWTON | NS_ORTHO) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_2D_NEWTON_H +#define LMP_NSTENCIL_HALF_BIN_2D_NEWTON_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin2dNewton : public NStencil { + public: + NStencilHalfBin2dNewton(class LAMMPS *); + ~NStencilHalfBin2dNewton() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_bin_2d_newton_tri.cpp b/src/nstencil_half_bin_2d_newton_tri.cpp new file mode 100644 index 0000000000..3a645a7434 --- /dev/null +++ b/src/nstencil_half_bin_2d_newton_tri.cpp @@ -0,0 +1,39 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_2d_newton_tri.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin2dNewtonTri::NStencilHalfBin2dNewtonTri(LAMMPS *lmp) : + NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfBin2dNewtonTri::create() +{ + int i,j; + + nstencil = 0; + + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) + stencil[nstencil++] = j*mbinx + i; +} diff --git a/src/nstencil_half_bin_2d_newton_tri.h b/src/nstencil_half_bin_2d_newton_tri.h new file mode 100644 index 0000000000..b9926608d7 --- /dev/null +++ b/src/nstencil_half_bin_2d_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/2d/newton/tri, + NStencilHalfBin2dNewtonTri, + NS_HALF | NS_BIN | NS_2D | NS_NEWTON | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_2D_NEWTON_TRI_H +#define LMP_NSTENCIL_HALF_BIN_2D_NEWTON_TRI_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin2dNewtonTri : public NStencil { + public: + NStencilHalfBin2dNewtonTri(class LAMMPS *); + ~NStencilHalfBin2dNewtonTri() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_bin_3d_newtoff.cpp b/src/nstencil_half_bin_3d_newtoff.cpp new file mode 100644 index 0000000000..44678b05df --- /dev/null +++ b/src/nstencil_half_bin_3d_newtoff.cpp @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_3d_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin3dNewtoff::NStencilHalfBin3dNewtoff(LAMMPS *lmp) : + NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfBin3dNewtoff::create() +{ + int i,j,k; + + 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) + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; +} diff --git a/src/nstencil_half_bin_3d_newtoff.h b/src/nstencil_half_bin_3d_newtoff.h new file mode 100644 index 0000000000..d1eac666cc --- /dev/null +++ b/src/nstencil_half_bin_3d_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/3d/newtoff, + NStencilHalfBin3dNewtoff, + NS_HALF | NS_BIN | NS_3D | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_3D_NEWTOFF_H +#define LMP_NSTENCIL_HALF_BIN_3D_NEWTOFF_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin3dNewtoff : public NStencil { + public: + NStencilHalfBin3dNewtoff(class LAMMPS *); + ~NStencilHalfBin3dNewtoff() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_bin_3d_newton.cpp b/src/nstencil_half_bin_3d_newton.cpp new file mode 100644 index 0000000000..24c234c004 --- /dev/null +++ b/src/nstencil_half_bin_3d_newton.cpp @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_3d_newton.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin3dNewton::NStencilHalfBin3dNewton(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfBin3dNewton::create() +{ + int i,j,k; + + nstencil = 0; + + for (k = 0; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (k > 0 || j > 0 || (j == 0 && i > 0)) + if (bin_distance(i,j,k) < cutneighmaxsq) + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; +} diff --git a/src/nstencil_half_bin_3d_newton.h b/src/nstencil_half_bin_3d_newton.h new file mode 100644 index 0000000000..96f19adae1 --- /dev/null +++ b/src/nstencil_half_bin_3d_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/3d/newton, + NStencilHalfBin3dNewton, + NS_HALF | NS_BIN | NS_3D | NS_NEWTON | NS_ORTHO) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_3D_NEWTON_H +#define LMP_NSTENCIL_HALF_BIN_3D_NEWTON_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin3dNewton : public NStencil { + public: + NStencilHalfBin3dNewton(class LAMMPS *); + ~NStencilHalfBin3dNewton() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_bin_3d_newton_tri.cpp b/src/nstencil_half_bin_3d_newton_tri.cpp new file mode 100644 index 0000000000..9e8c41f97a --- /dev/null +++ b/src/nstencil_half_bin_3d_newton_tri.cpp @@ -0,0 +1,40 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_bin_3d_newton_tri.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfBin3dNewtonTri::NStencilHalfBin3dNewtonTri(LAMMPS *lmp) : + NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfBin3dNewtonTri::create() +{ + int i,j,k; + + nstencil = 0; + + for (k = 0; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,k) < cutneighmaxsq) + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; +} diff --git a/src/nstencil_half_bin_3d_newton_tri.h b/src/nstencil_half_bin_3d_newton_tri.h new file mode 100644 index 0000000000..8c265acb46 --- /dev/null +++ b/src/nstencil_half_bin_3d_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/bin/3d/newton/tri, + NStencilHalfBin3dNewtonTri, + NS_HALF | NS_BIN | NS_3D | NS_NEWTON | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_BIN_3D_NEWTON_TRI_H +#define LMP_NSTENCIL_HALF_BIN_3D_NEWTON_TRI_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin3dNewtonTri : public NStencil { + public: + NStencilHalfBin3dNewtonTri(class LAMMPS *); + ~NStencilHalfBin3dNewtonTri() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_ghost_bin_2d_newtoff.cpp b/src/nstencil_half_ghost_bin_2d_newtoff.cpp new file mode 100644 index 0000000000..4bb0ecafe2 --- /dev/null +++ b/src/nstencil_half_ghost_bin_2d_newtoff.cpp @@ -0,0 +1,46 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_ghost_bin_2d_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfGhostBin2dNewtoff:: +NStencilHalfGhostBin2dNewtoff(LAMMPS *lmp) : NStencil(lmp) +{ + xyzflag = 1; +} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfGhostBin2dNewtoff::create() +{ + int i,j; + + nstencil = 0; + + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (bin_distance(i,j,0) < cutneighmaxsq) { + stencilxyz[nstencil][0] = i; + stencilxyz[nstencil][1] = j; + stencilxyz[nstencil][2] = 0; + stencil[nstencil++] = j*mbinx + i; + } +} diff --git a/src/nstencil_half_ghost_bin_2d_newtoff.h b/src/nstencil_half_ghost_bin_2d_newtoff.h new file mode 100644 index 0000000000..3b70f0042a --- /dev/null +++ b/src/nstencil_half_ghost_bin_2d_newtoff.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/ghost/bin/2d/newtoff, + NStencilHalfGhostBin2dNewtoff, + NS_HALF | NS_GHOST | NS_BIN | NS_2D | + NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_GHOST_BIN_2D_NEWTOFF_H +#define LMP_NSTENCIL_HALF_GHOST_BIN_2D_NEWTOFF_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfGhostBin2dNewtoff : public NStencil { + public: + NStencilHalfGhostBin2dNewtoff(class LAMMPS *); + ~NStencilHalfGhostBin2dNewtoff() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_ghost_bin_3d_newtoff.cpp b/src/nstencil_half_ghost_bin_3d_newtoff.cpp new file mode 100644 index 0000000000..1026b11542 --- /dev/null +++ b/src/nstencil_half_ghost_bin_3d_newtoff.cpp @@ -0,0 +1,47 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_ghost_bin_3d_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfGhostBin3dNewtoff:: +NStencilHalfGhostBin3dNewtoff(LAMMPS *lmp) : NStencil(lmp) +{ + xyzflag = 1; +} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfGhostBin3dNewtoff::create() +{ + int i,j,k; + + 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) { + stencilxyz[nstencil][0] = i; + stencilxyz[nstencil][1] = j; + stencilxyz[nstencil][2] = k; + stencil[nstencil++] = k*mbiny*mbinx + j*mbinx + i; + } +} diff --git a/src/nstencil_half_ghost_bin_3d_newtoff.h b/src/nstencil_half_ghost_bin_3d_newtoff.h new file mode 100644 index 0000000000..ee58c29342 --- /dev/null +++ b/src/nstencil_half_ghost_bin_3d_newtoff.h @@ -0,0 +1,44 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/ghost/bin/3d/newtoff, + NStencilHalfGhostBin3dNewtoff, + NS_HALF | NS_GHOST | NS_BIN | NS_3D | + NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_GHOST_BIN_3D_NEWTOFF_H +#define LMP_NSTENCIL_HALF_GHOST_BIN_3D_NEWTOFF_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfGhostBin3dNewtoff : public NStencil { + public: + NStencilHalfGhostBin3dNewtoff(class LAMMPS *); + ~NStencilHalfGhostBin3dNewtoff() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_multi_2d_newtoff.cpp b/src/nstencil_half_multi_2d_newtoff.cpp new file mode 100644 index 0000000000..567abe2878 --- /dev/null +++ b/src/nstencil_half_multi_2d_newtoff.cpp @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_multi_2d_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfMulti2dNewtoff:: +NStencilHalfMulti2dNewtoff(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfMulti2dNewtoff::create() +{ + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_half_multi_2d_newtoff.h b/src/nstencil_half_multi_2d_newtoff.h new file mode 100644 index 0000000000..5603f37beb --- /dev/null +++ b/src/nstencil_half_multi_2d_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/multi/2d/newtoff, + NStencilHalfMulti2dNewtoff, + NS_HALF | NS_MULTI | NS_2D | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_MULTI_2D_NEWTOFF_H +#define LMP_NSTENCIL_HALF_MULTI_2D_NEWTOFF_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfMulti2dNewtoff : public NStencil { + public: + NStencilHalfMulti2dNewtoff(class LAMMPS *); + ~NStencilHalfMulti2dNewtoff() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_multi_2d_newton.cpp b/src/nstencil_half_multi_2d_newton.cpp new file mode 100644 index 0000000000..5dc2c37148 --- /dev/null +++ b/src/nstencil_half_multi_2d_newton.cpp @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_multi_2d_newton.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfMulti2dNewton:: +NStencilHalfMulti2dNewton(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfMulti2dNewton::create() +{ + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (j > 0 || (j == 0 && i > 0)) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_half_multi_2d_newton.h b/src/nstencil_half_multi_2d_newton.h new file mode 100644 index 0000000000..9ecac4c696 --- /dev/null +++ b/src/nstencil_half_multi_2d_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/multi/2d/newton, + NStencilHalfMulti2dNewton, + NS_HALF | NS_MULTI | NS_2D | NS_NEWTON | NS_ORTHO) + +#else + +#ifndef LMP_NSTENCIL_HALF_MULTI_2D_NEWTON_H +#define LMP_NSTENCIL_HALF_MULTI_2D_NEWTON_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfMulti2dNewton : public NStencil { + public: + NStencilHalfMulti2dNewton(class LAMMPS *); + ~NStencilHalfMulti2dNewton() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_multi_2d_newton_tri.cpp b/src/nstencil_half_multi_2d_newton_tri.cpp new file mode 100644 index 0000000000..59a5a1d19e --- /dev/null +++ b/src/nstencil_half_multi_2d_newton_tri.cpp @@ -0,0 +1,53 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_multi_2d_newton_tri.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfMulti2dNewtonTri:: +NStencilHalfMulti2dNewtonTri(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfMulti2dNewtonTri::create() +{ + int i,j,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (j = 0; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,0); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_half_multi_2d_newton_tri.h b/src/nstencil_half_multi_2d_newton_tri.h new file mode 100644 index 0000000000..62d7dfdebf --- /dev/null +++ b/src/nstencil_half_multi_2d_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/multi/2d/newton/tri, + NStencilHalfMulti2dNewtonTri, + NS_HALF | NS_MULTI | NS_2D | NS_NEWTON | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_MULTI_2D_NEWTON_TRI_H +#define LMP_NSTENCIL_HALF_MULTI_2D_NEWTON_TRI_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfMulti2dNewtonTri : public NStencil { + public: + NStencilHalfMulti2dNewtonTri(class LAMMPS *); + ~NStencilHalfMulti2dNewtonTri() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_multi_3d_newtoff.cpp b/src/nstencil_half_multi_3d_newtoff.cpp new file mode 100644 index 0000000000..72b882dddc --- /dev/null +++ b/src/nstencil_half_multi_3d_newtoff.cpp @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_multi_3d_newtoff.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfMulti3dNewtoff:: +NStencilHalfMulti3dNewtoff(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfMulti3dNewtoff::create() +{ + int i,j,k,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (k = -sz; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,k); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = k*mbiny*mbinx + j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_half_multi_3d_newtoff.h b/src/nstencil_half_multi_3d_newtoff.h new file mode 100644 index 0000000000..99428deb6a --- /dev/null +++ b/src/nstencil_half_multi_3d_newtoff.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/multi/3d/newtoff, + NStencilHalfMulti3dNewtoff, + NS_HALF | NS_MULTI | NS_3D | NS_NEWTOFF | NS_ORTHO | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_MULTI_3D_NEWTOFF_H +#define LMP_NSTENCIL_HALF_MULTI_3D_NEWTOFF_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfMulti3dNewtoff : public NStencil { + public: + NStencilHalfMulti3dNewtoff(class LAMMPS *); + ~NStencilHalfMulti3dNewtoff() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_multi_3d_newton.cpp b/src/nstencil_half_multi_3d_newton.cpp new file mode 100644 index 0000000000..9a5d5cab65 --- /dev/null +++ b/src/nstencil_half_multi_3d_newton.cpp @@ -0,0 +1,55 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_multi_3d_newton.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfMulti3dNewton:: +NStencilHalfMulti3dNewton(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfMulti3dNewton::create() +{ + int i,j,k,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (k = 0; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) + if (k > 0 || j > 0 || (j == 0 && i > 0)) { + rsq = bin_distance(i,j,k); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = k*mbiny*mbinx + j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_half_multi_3d_newton.h b/src/nstencil_half_multi_3d_newton.h new file mode 100644 index 0000000000..bbdc7752c6 --- /dev/null +++ b/src/nstencil_half_multi_3d_newton.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/multi/3d/newton, + NStencilHalfMulti3dNewton, + NS_HALF | NS_MULTI | NS_3D | NS_NEWTON | NS_ORTHO) + +#else + +#ifndef LMP_NSTENCIL_HALF_MULTI_3D_NEWTON_H +#define LMP_NSTENCIL_HALF_MULTI_3D_NEWTON_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfMulti3dNewton : public NStencil { + public: + NStencilHalfMulti3dNewton(class LAMMPS *); + ~NStencilHalfMulti3dNewton() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/nstencil_half_multi_3d_newton_tri.cpp b/src/nstencil_half_multi_3d_newton_tri.cpp new file mode 100644 index 0000000000..953beb3211 --- /dev/null +++ b/src/nstencil_half_multi_3d_newton_tri.cpp @@ -0,0 +1,54 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include "nstencil_half_multi_3d_newton_tri.h" +#include "neighbor.h" +#include "neigh_list.h" +#include "atom.h" + +using namespace LAMMPS_NS; + +/* ---------------------------------------------------------------------- */ + +NStencilHalfMulti3dNewtonTri:: +NStencilHalfMulti3dNewtonTri(LAMMPS *lmp) : NStencil(lmp) {} + +/* ---------------------------------------------------------------------- + create stencil based on bin geometry and cutoff +------------------------------------------------------------------------- */ + +void NStencilHalfMulti3dNewtonTri::create() +{ + int i,j,k,n; + double rsq,typesq; + int *s; + double *distsq; + + int ntypes = atom->ntypes; + for (int itype = 1; itype <= ntypes; itype++) { + typesq = cuttypesq[itype]; + s = stencil_multi[itype]; + distsq = distsq_multi[itype]; + n = 0; + for (k = 0; k <= sz; k++) + for (j = -sy; j <= sy; j++) + for (i = -sx; i <= sx; i++) { + rsq = bin_distance(i,j,k); + if (rsq < typesq) { + distsq[n] = rsq; + s[n++] = k*mbiny*mbinx + j*mbinx + i; + } + } + nstencil_multi[itype] = n; + } +} diff --git a/src/nstencil_half_multi_3d_newton_tri.h b/src/nstencil_half_multi_3d_newton_tri.h new file mode 100644 index 0000000000..f6866489a4 --- /dev/null +++ b/src/nstencil_half_multi_3d_newton_tri.h @@ -0,0 +1,43 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NSTENCIL_CLASS + +NStencilStyle(half/multi/3d/newton/tri, + NStencilHalfMulti3dNewtonTri, + NS_HALF | NS_MULTI | NS_3D | NS_NEWTON | NS_TRI) + +#else + +#ifndef LMP_NSTENCIL_HALF_MULTI_3D_NEWTON_TRI_H +#define LMP_NSTENCIL_HALF_MULTI_3D_NEWTON_TRI_H + +#include "nstencil.h" + +namespace LAMMPS_NS { + +class NStencilHalfMulti3dNewtonTri : public NStencil { + public: + NStencilHalfMulti3dNewtonTri(class LAMMPS *); + ~NStencilHalfMulti3dNewtonTri() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo.cpp b/src/ntopo.cpp new file mode 100644 index 0000000000..124fa6687c --- /dev/null +++ b/src/ntopo.cpp @@ -0,0 +1,218 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo.h" +#include "atom.h" +#include "neighbor.h" +#include "comm.h" +#include "domain.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define LB_FACTOR 1.5 + +/* ---------------------------------------------------------------------- */ + +NTopo::NTopo(LAMMPS *lmp) : Pointers(lmp) +{ + me = comm->me; + nprocs = comm->nprocs; + + nbondlist = nanglelist = ndihedrallist = nimproperlist = 0; + maxbond = maxangle = maxdihedral = maximproper = 0; + bondlist = anglelist = dihedrallist = improperlist = NULL; + + cluster_check = neighbor->cluster_check; +} + +/* ---------------------------------------------------------------------- */ + +NTopo::~NTopo() +{ + memory->destroy(bondlist); + memory->destroy(anglelist); + memory->destroy(dihedrallist); + memory->destroy(improperlist); +} + +/* ---------------------------------------------------------------------- */ + +void NTopo::allocate_bond() +{ + if (nprocs == 1) maxbond = atom->nbonds; + else maxbond = static_cast (LB_FACTOR * atom->nbonds / nprocs); + memory->create(bondlist,maxbond,3,"neigh_topo:bondlist"); +} + +/* ---------------------------------------------------------------------- */ + +void NTopo::allocate_angle() +{ + if (nprocs == 1) maxangle = atom->nangles; + else maxangle = static_cast (LB_FACTOR * atom->nangles / nprocs); + memory->create(anglelist,maxangle,4,"neigh_topo:anglelist"); +} + +/* ---------------------------------------------------------------------- */ + +void NTopo::allocate_dihedral() +{ + if (nprocs == 1) maxdihedral = atom->ndihedrals; + else maxdihedral = static_cast (LB_FACTOR * atom->ndihedrals / nprocs); + memory->create(dihedrallist,maxdihedral,5,"neigh_topo:dihedrallist"); +} + +/* ---------------------------------------------------------------------- */ + +void NTopo::allocate_improper() +{ + if (nprocs == 1) maximproper = atom->nimpropers; + else maximproper = static_cast (LB_FACTOR * atom->nimpropers / nprocs); + memory->create(improperlist,maximproper,5,"neigh_topo:improperlist"); +} + +/* ---------------------------------------------------------------------- */ + +void NTopo::bond_check() +{ + int i,j; + double dx,dy,dz,dxstart,dystart,dzstart; + + double **x = atom->x; + int flag = 0; + + for (int m = 0; m < nbondlist; m++) { + i = bondlist[m][0]; + j = bondlist[m][1]; + dxstart = dx = x[i][0] - x[j][0]; + dystart = dy = x[i][1] - x[j][1]; + dzstart = dz = x[i][2] - x[j][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + } + + int flag_all; + MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); + if (flag_all) error->all(FLERR,"Bond extent > half of periodic box length"); +} + +/* ---------------------------------------------------------------------- */ + +void NTopo::angle_check() +{ + int i,j,k; + double dx,dy,dz,dxstart,dystart,dzstart; + + double **x = atom->x; + int flag = 0; + + // check all 3 distances + // in case angle potential computes any of them + + for (int m = 0; m < nanglelist; m++) { + i = anglelist[m][0]; + j = anglelist[m][1]; + k = anglelist[m][2]; + dxstart = dx = x[i][0] - x[j][0]; + dystart = dy = x[i][1] - x[j][1]; + dzstart = dz = x[i][2] - x[j][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x[i][0] - x[k][0]; + dystart = dy = x[i][1] - x[k][1]; + dzstart = dz = x[i][2] - x[k][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x[j][0] - x[k][0]; + dystart = dy = x[j][1] - x[k][1]; + dzstart = dz = x[j][2] - x[k][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + } + + int flag_all; + MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); + if (flag_all) error->all(FLERR,"Angle extent > half of periodic box length"); +} + +/* ---------------------------------------------------------------------- */ + +void NTopo::dihedral_check(int nlist, int **list) +{ + int i,j,k,l; + double dx,dy,dz,dxstart,dystart,dzstart; + + double **x = atom->x; + int flag = 0; + + // check all 6 distances + // in case dihedral/improper potential computes any of them + + for (int m = 0; m < nlist; m++) { + i = list[m][0]; + j = list[m][1]; + k = list[m][2]; + l = list[m][3]; + dxstart = dx = x[i][0] - x[j][0]; + dystart = dy = x[i][1] - x[j][1]; + dzstart = dz = x[i][2] - x[j][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x[i][0] - x[k][0]; + dystart = dy = x[i][1] - x[k][1]; + dzstart = dz = x[i][2] - x[k][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x[i][0] - x[l][0]; + dystart = dy = x[i][1] - x[l][1]; + dzstart = dz = x[i][2] - x[l][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x[j][0] - x[k][0]; + dystart = dy = x[j][1] - x[k][1]; + dzstart = dz = x[j][2] - x[k][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x[j][0] - x[l][0]; + dystart = dy = x[j][1] - x[l][1]; + dzstart = dz = x[j][2] - x[l][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + dxstart = dx = x[k][0] - x[l][0]; + dystart = dy = x[k][1] - x[l][1]; + dzstart = dz = x[k][2] - x[l][2]; + domain->minimum_image(dx,dy,dz); + if (dx != dxstart || dy != dystart || dz != dzstart) flag = 1; + } + + int flag_all; + MPI_Allreduce(&flag,&flag_all,1,MPI_INT,MPI_SUM,world); + if (flag_all) + error->all(FLERR,"Dihedral/improper extent > half of periodic box length"); +} + +/* ---------------------------------------------------------------------- */ + +bigint NTopo::memory_usage() +{ + bigint bytes = 0; + bytes += 3*maxbond * sizeof(int); + bytes += 4*maxangle * sizeof(int); + bytes += 5*maxdihedral * sizeof(int); + bytes += 5*maximproper * sizeof(int); + return bytes; +} + diff --git a/src/ntopo.h b/src/ntopo.h new file mode 100644 index 0000000000..672a82e367 --- /dev/null +++ b/src/ntopo.h @@ -0,0 +1,56 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifndef LMP_NTOPO_H +#define LMP_NTOPO_H + +#include "pointers.h" + +namespace LAMMPS_NS { + +class NTopo : protected Pointers { + public: + int nbondlist,nanglelist,ndihedrallist,nimproperlist; + int **bondlist,**anglelist,**dihedrallist,**improperlist; + + NTopo(class LAMMPS *); + virtual ~NTopo(); + + virtual void build() = 0; + + bigint memory_usage(); + + protected: + enum{IGNORE,WARN,ERROR}; // same as thermo.cpp + + int me,nprocs; + int maxbond,maxangle,maxdihedral,maximproper; + int cluster_check; // copy from Neighbor + + void allocate_bond(); + void allocate_angle(); + void allocate_dihedral(); + void allocate_improper(); + + void bond_check(); + void angle_check(); + void dihedral_check(int, int **); +}; + +} + +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_angle_all.cpp b/src/ntopo_angle_all.cpp new file mode 100644 index 0000000000..3a079ab467 --- /dev/null +++ b/src/ntopo_angle_all.cpp @@ -0,0 +1,99 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_angle_all.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoAngleAll::NTopoAngleAll(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_angle(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoAngleAll::build() +{ + int i,m,atom1,atom2,atom3; + + int nlocal = atom->nlocal; + 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 newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nanglelist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_angle[i]; m++) { + atom1 = atom->map(angle_atom1[i][m]); + atom2 = atom->map(angle_atom2[i][m]); + atom3 = atom->map(angle_atom3[i][m]); + if (atom1 == -1 || atom2 == -1 || atom3 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Angle atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m], + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { + if (nanglelist == maxangle) { + maxangle += DELTA; + memory->grow(anglelist,maxangle,4,"neigh_topo:anglelist"); + } + anglelist[nanglelist][0] = atom1; + anglelist[nanglelist][1] = atom2; + anglelist[nanglelist][2] = atom3; + anglelist[nanglelist][3] = angle_type[i][m]; + nanglelist++; + } + } + + if (cluster_check) angle_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/neigh_full.h b/src/ntopo_angle_all.h similarity index 68% rename from src/neigh_full.h rename to src/ntopo_angle_all.h index 1538f7662a..fad611a1eb 100644 --- a/src/neigh_full.h +++ b/src/ntopo_angle_all.h @@ -11,12 +11,31 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_ANGLE_ALL,NTopoAngleAll) + +#else + +#ifndef LMP_TOPO_ANGLE_ALL_H +#define LMP_TOPO_ANGLE_ALL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoAngleAll : public NTopo { + public: + NTopoAngleAll(class LAMMPS *); + ~NTopoAngleAll() {} + void build(); +}; + +} + +#endif +#endif + /* ERROR/WARNING messages: -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - */ diff --git a/src/ntopo_angle_partial.cpp b/src/ntopo_angle_partial.cpp new file mode 100644 index 0000000000..f1d668a3ba --- /dev/null +++ b/src/ntopo_angle_partial.cpp @@ -0,0 +1,100 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_angle_partial.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoAnglePartial::NTopoAnglePartial(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_angle(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoAnglePartial::build() +{ + int i,m,atom1,atom2,atom3; + + int nlocal = atom->nlocal; + 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 newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nanglelist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_angle[i]; m++) { + if (angle_type[i][m] <= 0) continue; + atom1 = atom->map(angle_atom1[i][m]); + atom2 = atom->map(angle_atom2[i][m]); + atom3 = atom->map(angle_atom3[i][m]); + if (atom1 == -1 || atom2 == -1 || atom3 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Angle atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + angle_atom1[i][m],angle_atom2[i][m],angle_atom3[i][m], + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { + if (nanglelist == maxangle) { + maxangle += DELTA; + memory->grow(anglelist,maxangle,4,"neigh_topo:anglelist"); + } + anglelist[nanglelist][0] = atom1; + anglelist[nanglelist][1] = atom2; + anglelist[nanglelist][2] = atom3; + anglelist[nanglelist][3] = angle_type[i][m]; + nanglelist++; + } + } + + if (cluster_check) angle_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_angle_partial.h b/src/ntopo_angle_partial.h new file mode 100644 index 0000000000..57ebcec558 --- /dev/null +++ b/src/ntopo_angle_partial.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_ANGLE_PARTIAL,NTopoAnglePartial) + +#else + +#ifndef LMP_TOPO_ANGLE_PARTIAL_H +#define LMP_TOPO_ANGLE_PARTIAL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoAnglePartial : public NTopo { + public: + NTopoAnglePartial(class LAMMPS *); + ~NTopoAnglePartial() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_angle_template.cpp b/src/ntopo_angle_template.cpp new file mode 100644 index 0000000000..05d5de28a4 --- /dev/null +++ b/src/ntopo_angle_template.cpp @@ -0,0 +1,119 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_angle_template.h" +#include "atom.h" +#include "atom_vec.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "molecule.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoAngleTemplate::NTopoAngleTemplate(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_angle(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoAngleTemplate::build() +{ + int i,m,atom1,atom2,atom3; + int imol,iatom; + tagint tagprev; + int *num_angle; + tagint **angle_atom1,**angle_atom2,**angle_atom3; + int **angle_type; + + Molecule **onemols = atom->avec->onemols; + + tagint *tag = atom->tag; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nanglelist = 0; + + for (i = 0; i < nlocal; i++) { + if (molindex[i] < 0) continue; + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + num_angle = onemols[imol]->num_angle; + angle_atom1 = onemols[imol]->angle_atom1; + angle_atom2 = onemols[imol]->angle_atom2; + angle_atom3 = onemols[imol]->angle_atom3; + angle_type = onemols[imol]->angle_type; + + for (m = 0; m < num_angle[iatom]; m++) { + if (angle_type[iatom][m] <= 0) continue; + atom1 = atom->map(angle_atom1[iatom][m]+tagprev); + atom2 = atom->map(angle_atom2[iatom][m]+tagprev); + atom3 = atom->map(angle_atom3[iatom][m]+tagprev); + if (atom1 == -1 || atom2 == -1 || atom3 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Angle atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + angle_atom1[iatom][m]+tagprev,angle_atom2[iatom][m]+tagprev, + angle_atom3[iatom][m]+tagprev, + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + if (newton_bond || (i <= atom1 && i <= atom2 && i <= atom3)) { + if (nanglelist == maxangle) { + maxangle += DELTA; + memory->grow(anglelist,maxangle,4,"neigh_topo:anglelist"); + } + anglelist[nanglelist][0] = atom1; + anglelist[nanglelist][1] = atom2; + anglelist[nanglelist][2] = atom3; + anglelist[nanglelist][3] = angle_type[iatom][m]; + nanglelist++; + } + } + } + + if (cluster_check) angle_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Angle atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_angle_template.h b/src/ntopo_angle_template.h new file mode 100644 index 0000000000..fc94a07b02 --- /dev/null +++ b/src/ntopo_angle_template.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_ANGLE_TEMPLATE,NTopoAngleTemplate) + +#else + +#ifndef LMP_TOPO_ANGLE_TEMPLATE_H +#define LMP_TOPO_ANGLE_TEMPLATE_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoAngleTemplate : public NTopo { + public: + NTopoAngleTemplate(class LAMMPS *); + ~NTopoAngleTemplate() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_bond_all.cpp b/src/ntopo_bond_all.cpp new file mode 100644 index 0000000000..03cb2ad86b --- /dev/null +++ b/src/ntopo_bond_all.cpp @@ -0,0 +1,91 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_bond_all.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoBondAll::NTopoBondAll(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_bond(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoBondAll::build() +{ + int i,m,atom1; + + int nlocal = atom->nlocal; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + tagint *tag = atom->tag; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nbondlist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_bond[i]; m++) { + atom1 = atom->map(bond_atom[i][m]); + if (atom1 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + tag[i],bond_atom[i][m],me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + if (newton_bond || i < atom1) { + if (nbondlist == maxbond) { + maxbond += DELTA; + memory->grow(bondlist,maxbond,3,"neigh_topo:bondlist"); + } + bondlist[nbondlist][0] = i; + bondlist[nbondlist][1] = atom1; + bondlist[nbondlist][2] = bond_type[i][m]; + nbondlist++; + } + } + + if (cluster_check) bond_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/neigh_derive.h b/src/ntopo_bond_all.h similarity index 68% rename from src/neigh_derive.h rename to src/ntopo_bond_all.h index 1538f7662a..8c89d66431 100644 --- a/src/neigh_derive.h +++ b/src/ntopo_bond_all.h @@ -11,12 +11,31 @@ See the README file in the top-level LAMMPS directory. ------------------------------------------------------------------------- */ +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_BOND_ALL,NTopoBondAll) + +#else + +#ifndef LMP_TOPO_BOND_ALL_H +#define LMP_TOPO_BOND_ALL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoBondAll : public NTopo { + public: + NTopoBondAll(class LAMMPS *); + ~NTopoBondAll() {} + void build(); +}; + +} + +#endif +#endif + /* ERROR/WARNING messages: -E: Neighbor list overflow, boost neigh_modify one - -There are too many neighbors of a single atom. Use the neigh_modify -command to increase the max number of neighbors allowed for one atom. -You may also want to boost the page size. - */ diff --git a/src/ntopo_bond_partial.cpp b/src/ntopo_bond_partial.cpp new file mode 100644 index 0000000000..cda4bdcf09 --- /dev/null +++ b/src/ntopo_bond_partial.cpp @@ -0,0 +1,92 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_bond_partial.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoBondPartial::NTopoBondPartial(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_bond(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoBondPartial::build() +{ + int i,m,atom1; + + int nlocal = atom->nlocal; + int *num_bond = atom->num_bond; + tagint **bond_atom = atom->bond_atom; + int **bond_type = atom->bond_type; + tagint *tag = atom->tag; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nbondlist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_bond[i]; m++) { + if (bond_type[i][m] <= 0) continue; + atom1 = atom->map(bond_atom[i][m]); + if (atom1 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + tag[i],bond_atom[i][m],me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + if (newton_bond || i < atom1) { + if (nbondlist == maxbond) { + maxbond += DELTA; + memory->grow(bondlist,maxbond,3,"neigh_topo:bondlist"); + } + bondlist[nbondlist][0] = i; + bondlist[nbondlist][1] = atom1; + bondlist[nbondlist][2] = bond_type[i][m]; + nbondlist++; + } + } + + if (cluster_check) bond_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_bond_partial.h b/src/ntopo_bond_partial.h new file mode 100644 index 0000000000..b0a2c274b2 --- /dev/null +++ b/src/ntopo_bond_partial.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_BOND_PARTIAL,NTopoBondPartial) + +#else + +#ifndef LMP_TOPO_BOND_PARTIAL_H +#define LMP_TOPO_BOND_PARTIAL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoBondPartial : public NTopo { + public: + NTopoBondPartial(class LAMMPS *); + ~NTopoBondPartial() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_bond_template.cpp b/src/ntopo_bond_template.cpp new file mode 100644 index 0000000000..de16d78585 --- /dev/null +++ b/src/ntopo_bond_template.cpp @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_bond_template.h" +#include "atom.h" +#include "atom_vec.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "molecule.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoBondTemplate::NTopoBondTemplate(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_bond(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoBondTemplate::build() +{ + int i,m,atom1; + int imol,iatom; + tagint tagprev; + int *num_bond; + tagint **bond_atom; + int **bond_type; + + Molecule **onemols = atom->avec->onemols; + + tagint *tag = atom->tag; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nbondlist = 0; + + for (i = 0; i < nlocal; i++) { + if (molindex[i] < 0) continue; + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + num_bond = onemols[imol]->num_bond; + bond_atom = onemols[imol]->bond_atom; + bond_type = onemols[imol]->bond_type; + + for (m = 0; m < num_bond[iatom]; m++) { + if (bond_type[iatom][m] <= 0) continue; + atom1 = atom->map(bond_atom[iatom][m]+tagprev); + if (atom1 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Bond atoms " TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + tag[i],bond_atom[iatom][m]+tagprev,me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + if (newton_bond || i < atom1) { + if (nbondlist == maxbond) { + maxbond += DELTA; + memory->grow(bondlist,maxbond,3,"neigh_topo:bondlist"); + } + bondlist[nbondlist][0] = i; + bondlist[nbondlist][1] = atom1; + bondlist[nbondlist][2] = bond_type[iatom][m]; + nbondlist++; + } + } + } + + if (cluster_check) bond_check(); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Bond atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_bond_template.h b/src/ntopo_bond_template.h new file mode 100644 index 0000000000..6d0aeb001f --- /dev/null +++ b/src/ntopo_bond_template.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_BOND_TEMPLATE,NTopoBondTemplate) + +#else + +#ifndef LMP_TOPO_BOND_TEMPLATE_H +#define LMP_TOPO_BOND_TEMPLATE_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoBondTemplate : public NTopo { + public: + NTopoBondTemplate(class LAMMPS *); + ~NTopoBondTemplate() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_dihedral_all.cpp b/src/ntopo_dihedral_all.cpp new file mode 100644 index 0000000000..7a5b350fa0 --- /dev/null +++ b/src/ntopo_dihedral_all.cpp @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_dihedral_all.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoDihedralAll::NTopoDihedralAll(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_dihedral(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoDihedralAll::build() +{ + int i,m,atom1,atom2,atom3,atom4; + + int nlocal = atom->nlocal; + 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 **dihedral_type = atom->dihedral_type; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + ndihedrallist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_dihedral[i]; m++) { + atom1 = atom->map(dihedral_atom1[i][m]); + atom2 = atom->map(dihedral_atom2[i][m]); + atom3 = atom->map(dihedral_atom3[i][m]); + atom4 = atom->map(dihedral_atom4[i][m]); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Dihedral atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " + TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + dihedral_atom1[i][m],dihedral_atom2[i][m], + dihedral_atom3[i][m],dihedral_atom4[i][m], + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + atom4 = domain->closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + if (ndihedrallist == maxdihedral) { + maxdihedral += DELTA; + memory->grow(dihedrallist,maxdihedral,5,"neigh_topo:dihedrallist"); + } + dihedrallist[ndihedrallist][0] = atom1; + dihedrallist[ndihedrallist][1] = atom2; + dihedrallist[ndihedrallist][2] = atom3; + dihedrallist[ndihedrallist][3] = atom4; + dihedrallist[ndihedrallist][4] = dihedral_type[i][m]; + ndihedrallist++; + } + } + + if (cluster_check) dihedral_check(ndihedrallist,dihedrallist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_dihedral_all.h b/src/ntopo_dihedral_all.h new file mode 100644 index 0000000000..45a5711687 --- /dev/null +++ b/src/ntopo_dihedral_all.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_DIHEDRAL_ALL,NTopoDihedralAll) + +#else + +#ifndef LMP_TOPO_DIHEDRAL_ALL_H +#define LMP_TOPO_DIHEDRAL_ALL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoDihedralAll : public NTopo { + public: + NTopoDihedralAll(class LAMMPS *); + ~NTopoDihedralAll() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_dihedral_partial.cpp b/src/ntopo_dihedral_partial.cpp new file mode 100644 index 0000000000..abfc30ba31 --- /dev/null +++ b/src/ntopo_dihedral_partial.cpp @@ -0,0 +1,108 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_dihedral_partial.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoDihedralPartial::NTopoDihedralPartial(LAMMPS *lmp) : + NTopo(lmp) +{ + allocate_dihedral(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoDihedralPartial::build() +{ + int i,m,atom1,atom2,atom3,atom4; + + int nlocal = atom->nlocal; + 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 **dihedral_type = atom->dihedral_type; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + ndihedrallist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_dihedral[i]; m++) { + if (dihedral_type[i][m] <= 0) continue; + atom1 = atom->map(dihedral_atom1[i][m]); + atom2 = atom->map(dihedral_atom2[i][m]); + atom3 = atom->map(dihedral_atom3[i][m]); + atom4 = atom->map(dihedral_atom4[i][m]); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Dihedral atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " + TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + dihedral_atom1[i][m],dihedral_atom2[i][m], + dihedral_atom3[i][m],dihedral_atom4[i][m], + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + atom4 = domain->closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + if (ndihedrallist == maxdihedral) { + maxdihedral += DELTA; + memory->grow(dihedrallist,maxdihedral,5,"neigh_topo:dihedrallist"); + } + dihedrallist[ndihedrallist][0] = atom1; + dihedrallist[ndihedrallist][1] = atom2; + dihedrallist[ndihedrallist][2] = atom3; + dihedrallist[ndihedrallist][3] = atom4; + dihedrallist[ndihedrallist][4] = dihedral_type[i][m]; + ndihedrallist++; + } + } + + if (cluster_check) dihedral_check(ndihedrallist,dihedrallist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_dihedral_partial.h b/src/ntopo_dihedral_partial.h new file mode 100644 index 0000000000..a71022a601 --- /dev/null +++ b/src/ntopo_dihedral_partial.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_DIHEDRAL_PARTIAL,NTopoDihedralPartial) + +#else + +#ifndef LMP_TOPO_DIHEDRAL_PARTIAL_H +#define LMP_TOPO_DIHEDRAL_PARTIAL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoDihedralPartial : public NTopo { + public: + NTopoDihedralPartial(class LAMMPS *); + ~NTopoDihedralPartial() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_dihedral_template.cpp b/src/ntopo_dihedral_template.cpp new file mode 100644 index 0000000000..8ef60de237 --- /dev/null +++ b/src/ntopo_dihedral_template.cpp @@ -0,0 +1,127 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_dihedral_template.h" +#include "atom.h" +#include "atom_vec.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "molecule.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoDihedralTemplate::NTopoDihedralTemplate(LAMMPS *lmp) : + NTopo(lmp) +{ + allocate_dihedral(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoDihedralTemplate::build() +{ + int i,m,atom1,atom2,atom3,atom4; + int imol,iatom; + tagint tagprev; + int *num_dihedral; + tagint **dihedral_atom1,**dihedral_atom2,**dihedral_atom3,**dihedral_atom4; + int **dihedral_type; + + Molecule **onemols = atom->avec->onemols; + + tagint *tag = atom->tag; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + ndihedrallist = 0; + + for (i = 0; i < nlocal; i++) { + if (molindex[i] < 0) continue; + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + num_dihedral = onemols[imol]->num_dihedral; + dihedral_atom1 = onemols[imol]->dihedral_atom1; + dihedral_atom2 = onemols[imol]->dihedral_atom2; + dihedral_atom3 = onemols[imol]->dihedral_atom3; + dihedral_atom4 = onemols[imol]->dihedral_atom4; + dihedral_type = onemols[imol]->dihedral_type; + + for (m = 0; m < num_dihedral[iatom]; m++) { + atom1 = atom->map(dihedral_atom1[iatom][m]+tagprev); + atom2 = atom->map(dihedral_atom2[iatom][m]+tagprev); + atom3 = atom->map(dihedral_atom3[iatom][m]+tagprev); + atom4 = atom->map(dihedral_atom4[iatom][m]+tagprev); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Dihedral atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " + TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + dihedral_atom1[iatom][m]+tagprev, + dihedral_atom2[iatom][m]+tagprev, + dihedral_atom3[iatom][m]+tagprev, + dihedral_atom4[iatom][m]+tagprev, + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + atom4 = domain->closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + if (ndihedrallist == maxdihedral) { + maxdihedral += DELTA; + memory->grow(dihedrallist,maxdihedral,5,"neigh_topo:dihedrallist"); + } + dihedrallist[ndihedrallist][0] = atom1; + dihedrallist[ndihedrallist][1] = atom2; + dihedrallist[ndihedrallist][2] = atom3; + dihedrallist[ndihedrallist][3] = atom4; + dihedrallist[ndihedrallist][4] = dihedral_type[iatom][m]; + ndihedrallist++; + } + } + } + + if (cluster_check) dihedral_check(ndihedrallist,dihedrallist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Dihedral atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_dihedral_template.h b/src/ntopo_dihedral_template.h new file mode 100644 index 0000000000..c289fb6b7d --- /dev/null +++ b/src/ntopo_dihedral_template.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_DIHEDRAL_TEMPLATE,NTopoDihedralTemplate) + +#else + +#ifndef LMP_TOPO_DIHEDRAL_TEMPLATE_H +#define LMP_TOPO_DIHEDRAL_TEMPLATE_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoDihedralTemplate : public NTopo { + public: + NTopoDihedralTemplate(class LAMMPS *); + ~NTopoDihedralTemplate() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_improper_all.cpp b/src/ntopo_improper_all.cpp new file mode 100644 index 0000000000..ada3927e79 --- /dev/null +++ b/src/ntopo_improper_all.cpp @@ -0,0 +1,106 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_improper_all.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoImproperAll::NTopoImproperAll(LAMMPS *lmp) : NTopo(lmp) +{ + allocate_improper(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoImproperAll::build() +{ + int i,m,atom1,atom2,atom3,atom4; + + int nlocal = atom->nlocal; + int *num_improper = atom->num_improper; + tagint **improper_atom1 = atom->improper_atom1; + tagint **improper_atom2 = atom->improper_atom2; + tagint **improper_atom3 = atom->improper_atom3; + tagint **improper_atom4 = atom->improper_atom4; + int **improper_type = atom->improper_type; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nimproperlist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_improper[i]; m++) { + atom1 = atom->map(improper_atom1[i][m]); + atom2 = atom->map(improper_atom2[i][m]); + atom3 = atom->map(improper_atom3[i][m]); + atom4 = atom->map(improper_atom4[i][m]); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Improper atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " + TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + improper_atom1[i][m],improper_atom2[i][m], + improper_atom3[i][m],improper_atom4[i][m], + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + atom4 = domain-> closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + if (nimproperlist == maximproper) { + maximproper += DELTA; + memory->grow(improperlist,maximproper,5,"neigh_topo:improperlist"); + } + improperlist[nimproperlist][0] = atom1; + improperlist[nimproperlist][1] = atom2; + improperlist[nimproperlist][2] = atom3; + improperlist[nimproperlist][3] = atom4; + improperlist[nimproperlist][4] = improper_type[i][m]; + nimproperlist++; + } + } + + if (cluster_check) dihedral_check(nimproperlist,improperlist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_improper_all.h b/src/ntopo_improper_all.h new file mode 100644 index 0000000000..b7d9a9f049 --- /dev/null +++ b/src/ntopo_improper_all.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_IMPROPER_ALL,NTopoImproperAll) + +#else + +#ifndef LMP_TOPO_IMPROPER_ALL_H +#define LMP_TOPO_IMPROPER_ALL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoImproperAll : public NTopo { + public: + NTopoImproperAll(class LAMMPS *); + ~NTopoImproperAll() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_improper_partial.cpp b/src/ntopo_improper_partial.cpp new file mode 100644 index 0000000000..f8f06cf41b --- /dev/null +++ b/src/ntopo_improper_partial.cpp @@ -0,0 +1,108 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_improper_partial.h" +#include "atom.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoImproperPartial::NTopoImproperPartial(LAMMPS *lmp) : + NTopo(lmp) +{ + allocate_improper(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoImproperPartial::build() +{ + int i,m,atom1,atom2,atom3,atom4; + + int nlocal = atom->nlocal; + int *num_improper = atom->num_improper; + tagint **improper_atom1 = atom->improper_atom1; + tagint **improper_atom2 = atom->improper_atom2; + tagint **improper_atom3 = atom->improper_atom3; + tagint **improper_atom4 = atom->improper_atom4; + int **improper_type = atom->improper_type; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nimproperlist = 0; + + for (i = 0; i < nlocal; i++) + for (m = 0; m < num_improper[i]; m++) { + if (improper_type[i][m] <= 0) continue; + atom1 = atom->map(improper_atom1[i][m]); + atom2 = atom->map(improper_atom2[i][m]); + atom3 = atom->map(improper_atom3[i][m]); + atom4 = atom->map(improper_atom4[i][m]); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Improper atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " + TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + improper_atom1[i][m],improper_atom2[i][m], + improper_atom3[i][m],improper_atom4[i][m], + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + atom4 = domain->closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + if (nimproperlist == maximproper) { + maximproper += DELTA; + memory->grow(improperlist,maximproper,5,"neigh_topo:improperlist"); + } + improperlist[nimproperlist][0] = atom1; + improperlist[nimproperlist][1] = atom2; + improperlist[nimproperlist][2] = atom3; + improperlist[nimproperlist][3] = atom4; + improperlist[nimproperlist][4] = improper_type[i][m]; + nimproperlist++; + } + } + + if (cluster_check) dihedral_check(nimproperlist,improperlist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_improper_partial.h b/src/ntopo_improper_partial.h new file mode 100644 index 0000000000..45a9673e67 --- /dev/null +++ b/src/ntopo_improper_partial.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_IMPROPER_PARTIAL,NTopoImproperPartial) + +#else + +#ifndef LMP_TOPO_IMPROPER_PARTIAL_H +#define LMP_TOPO_IMPROPER_PARTIAL_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoImproperPartial : public NTopo { + public: + NTopoImproperPartial(class LAMMPS *); + ~NTopoImproperPartial() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ diff --git a/src/ntopo_improper_template.cpp b/src/ntopo_improper_template.cpp new file mode 100644 index 0000000000..4662e3693f --- /dev/null +++ b/src/ntopo_improper_template.cpp @@ -0,0 +1,127 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Templatel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include +#include "ntopo_improper_template.h" +#include "atom.h" +#include "atom_vec.h" +#include "force.h" +#include "domain.h" +#include "update.h" +#include "output.h" +#include "thermo.h" +#include "molecule.h" +#include "memory.h" +#include "error.h" + +using namespace LAMMPS_NS; + +#define DELTA 10000 + +/* ---------------------------------------------------------------------- */ + +NTopoImproperTemplate::NTopoImproperTemplate(LAMMPS *lmp) : + NTopo(lmp) +{ + allocate_improper(); +} + +/* ---------------------------------------------------------------------- */ + +void NTopoImproperTemplate::build() +{ + int i,m,atom1,atom2,atom3,atom4; + int imol,iatom; + tagint tagprev; + int *num_improper; + tagint **improper_atom1,**improper_atom2,**improper_atom3,**improper_atom4; + int **improper_type; + + Molecule **onemols = atom->avec->onemols; + + tagint *tag = atom->tag; + int *molindex = atom->molindex; + int *molatom = atom->molatom; + int nlocal = atom->nlocal; + int newton_bond = force->newton_bond; + + int lostbond = output->thermo->lostbond; + int nmissing = 0; + nimproperlist = 0; + + for (i = 0; i < nlocal; i++) { + if (molindex[i] < 0) continue; + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + num_improper = onemols[imol]->num_improper; + improper_atom1 = onemols[imol]->improper_atom1; + improper_atom2 = onemols[imol]->improper_atom2; + improper_atom3 = onemols[imol]->improper_atom3; + improper_atom4 = onemols[imol]->improper_atom4; + improper_type = onemols[imol]->improper_type; + + for (m = 0; m < num_improper[iatom]; m++) { + atom1 = atom->map(improper_atom1[iatom][m]+tagprev); + atom2 = atom->map(improper_atom2[iatom][m]+tagprev); + atom3 = atom->map(improper_atom3[iatom][m]+tagprev); + atom4 = atom->map(improper_atom4[iatom][m]+tagprev); + if (atom1 == -1 || atom2 == -1 || atom3 == -1 || atom4 == -1) { + nmissing++; + if (lostbond == ERROR) { + char str[128]; + sprintf(str,"Improper atoms " + TAGINT_FORMAT " " TAGINT_FORMAT " " + TAGINT_FORMAT " " TAGINT_FORMAT + " missing on proc %d at step " BIGINT_FORMAT, + improper_atom1[iatom][m]+tagprev, + improper_atom2[iatom][m]+tagprev, + improper_atom3[iatom][m]+tagprev, + improper_atom4[iatom][m]+tagprev, + me,update->ntimestep); + error->one(FLERR,str); + } + continue; + } + atom1 = domain->closest_image(i,atom1); + atom2 = domain->closest_image(i,atom2); + atom3 = domain->closest_image(i,atom3); + atom4 = domain-> closest_image(i,atom4); + if (newton_bond || + (i <= atom1 && i <= atom2 && i <= atom3 && i <= atom4)) { + if (nimproperlist == maximproper) { + maximproper += DELTA; + memory->grow(improperlist,maximproper,5,"neigh_topo:improperlist"); + } + improperlist[nimproperlist][0] = atom1; + improperlist[nimproperlist][1] = atom2; + improperlist[nimproperlist][2] = atom3; + improperlist[nimproperlist][3] = atom4; + improperlist[nimproperlist][4] = improper_type[iatom][m]; + nimproperlist++; + } + } + } + + if (cluster_check) dihedral_check(nimproperlist,improperlist); + if (lostbond == IGNORE) return; + + int all; + MPI_Allreduce(&nmissing,&all,1,MPI_INT,MPI_SUM,world); + if (all) { + char str[128]; + sprintf(str, + "Improper atoms missing at step " BIGINT_FORMAT,update->ntimestep); + if (me == 0) error->warning(FLERR,str); + } +} diff --git a/src/ntopo_improper_template.h b/src/ntopo_improper_template.h new file mode 100644 index 0000000000..fc760d021e --- /dev/null +++ b/src/ntopo_improper_template.h @@ -0,0 +1,41 @@ +/* -*- c++ -*- ---------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_IMPROPER_TEMPLATE,NTopoImproperTemplate) + +#else + +#ifndef LMP_TOPO_IMPROPER_TEMPLATE_H +#define LMP_TOPO_IMPROPER_TEMPLATE_H + +#include "ntopo.h" + +namespace LAMMPS_NS { + +class NTopoImproperTemplate : public NTopo { + public: + NTopoImproperTemplate(class LAMMPS *); + ~NTopoImproperTemplate() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/