1
/* -*- c++ -*- ----------------------------------------------------------
2
LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
3
http://lammps.sandia.gov, Sandia National Laboratories
4
Steve Plimpton, sjplimp@sandia.gov
6
Copyright (2003) Sandia Corporation. Under the terms of Contract
7
DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
8
certain rights in this software. This software is distributed under
9
the GNU General Public License.
11
See the README file in the top-level LAMMPS directory.
12
------------------------------------------------------------------------- */
14
#include "atom_kokkos.h"
15
#include "atom_masks.h"
16
#include "domain_kokkos.h"
18
using namespace LAMMPS_NS;
20
/* ---------------------------------------------------------------------- */
22
template<class DeviceType, int HALF_NEIGH>
23
void NeighborKokkos::full_bin_kokkos(NeighListKokkos<DeviceType> *list)
25
const int nall = includegroup?atom->nfirst:atom->nlocal;
28
NeighborKokkosExecute<DeviceType>
30
k_cutneighsq.view<DeviceType>(),
31
k_bincount.view<DeviceType>(),
32
k_bins.view<DeviceType>(),nall,
33
atomKK->k_x.view<DeviceType>(),
34
atomKK->k_type.view<DeviceType>(),
35
atomKK->k_mask.view<DeviceType>(),
36
atomKK->k_molecule.view<DeviceType>(),
37
atomKK->k_tag.view<DeviceType>(),
38
atomKK->k_special.view<DeviceType>(),
39
atomKK->k_nspecial.view<DeviceType>(),
41
nbinx,nbiny,nbinz,mbinx,mbiny,mbinz,mbinxlo,mbinylo,mbinzlo,
42
bininvx,bininvy,bininvz,
43
exclude, nex_type,maxex_type,
44
k_ex1_type.view<DeviceType>(),
45
k_ex2_type.view<DeviceType>(),
46
k_ex_type.view<DeviceType>(),
47
nex_group,maxex_group,
48
k_ex1_group.view<DeviceType>(),
49
k_ex2_group.view<DeviceType>(),
50
k_ex1_bit.view<DeviceType>(),
51
k_ex2_bit.view<DeviceType>(),
53
k_ex_mol_group.view<DeviceType>(),
54
k_ex_mol_bit.view<DeviceType>(),
56
domain->xperiodic,domain->yperiodic,domain->zperiodic,
57
domain->xprd_half,domain->yprd_half,domain->zprd_half);
59
k_cutneighsq.sync<DeviceType>();
60
k_ex1_type.sync<DeviceType>();
61
k_ex2_type.sync<DeviceType>();
62
k_ex_type.sync<DeviceType>();
63
k_ex1_group.sync<DeviceType>();
64
k_ex2_group.sync<DeviceType>();
65
k_ex1_bit.sync<DeviceType>();
66
k_ex2_bit.sync<DeviceType>();
67
k_ex_mol_group.sync<DeviceType>();
68
k_ex_mol_bit.sync<DeviceType>();
69
atomKK->sync(Device,X_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK);
70
Kokkos::deep_copy(list->d_stencil,list->h_stencil);
72
data.special_flag[0] = special_flag[0];
73
data.special_flag[1] = special_flag[1];
74
data.special_flag[2] = special_flag[2];
75
data.special_flag[3] = special_flag[3];
77
while(data.h_resize() > 0) {
79
deep_copy(data.resize, data.h_resize);
81
MemsetZeroFunctor<DeviceType> f_zero;
82
f_zero.ptr = (void*) k_bincount.view<DeviceType>().ptr_on_device();
83
Kokkos::parallel_for(mbins, f_zero);
86
NeighborKokkosBinAtomsFunctor<DeviceType> f(data);
88
Kokkos::parallel_for(atom->nlocal+atom->nghost, f);
91
deep_copy(data.h_resize, data.resize);
95
k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin);
96
data.bins = k_bins.view<DeviceType>();
97
data.c_bins = data.bins;
101
if(list->d_neighbors.dimension_0()<nall) {
102
list->d_neighbors = typename ArrayTypes<DeviceType>::t_neighbors_2d("neighbors", nall*1.1, list->maxneighs);
103
list->d_numneigh = typename ArrayTypes<DeviceType>::t_int_1d("numneigh", nall*1.1);
104
data.neigh_list.d_neighbors = list->d_neighbors;
105
data.neigh_list.d_numneigh = list->d_numneigh;
108
while(data.h_resize()) {
109
data.h_new_maxneighs() = list->maxneighs;
112
Kokkos::deep_copy(data.resize, data.h_resize);
113
Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs);
114
#ifdef KOKKOS_HAVE_CUDA
115
#define BINS_PER_BLOCK 2
116
const int factor = atoms_per_bin<64?2:1;
117
Kokkos::TeamPolicy<DeviceType> config((mbins+factor-1)/factor,atoms_per_bin*factor);
119
const int factor = 1;
123
NeighborKokkosBuildFunctor<DeviceType,HALF_NEIGH,1> f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor);
124
#ifdef KOKKOS_HAVE_CUDA
125
Kokkos::parallel_for(config, f);
127
Kokkos::parallel_for(nall, f);
130
NeighborKokkosBuildFunctor<DeviceType,HALF_NEIGH,0> f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor);
131
#ifdef KOKKOS_HAVE_CUDA
132
Kokkos::parallel_for(config, f);
134
Kokkos::parallel_for(nall, f);
138
deep_copy(data.h_resize, data.resize);
140
if(data.h_resize()) {
141
deep_copy(data.h_new_maxneighs, data.new_maxneighs);
142
list->maxneighs = data.h_new_maxneighs() * 1.2;
143
list->d_neighbors = typename ArrayTypes<DeviceType>::t_neighbors_2d("neighbors", list->d_neighbors.dimension_0(), list->maxneighs);
144
data.neigh_list.d_neighbors = list->d_neighbors;
145
data.neigh_list.maxneighs = list->maxneighs;
154
/* ---------------------------------------------------------------------- */
156
template<class Device>
157
KOKKOS_INLINE_FUNCTION
158
void NeighborKokkosExecute<Device>::binatomsItem(const int &i) const
160
const int ibin = coord2bin(x(i, 0), x(i, 1), x(i, 2));
162
const int ac = Kokkos::atomic_fetch_add(&bincount[ibin], (int)1);
163
if(ac < bins.dimension_1()) {
170
/* ---------------------------------------------------------------------- */
171
template<class Device>
172
KOKKOS_INLINE_FUNCTION
173
int NeighborKokkosExecute<Device>::find_special(const int &i, const int &j) const
175
const int n1 = nspecial(i,0);
176
const int n2 = nspecial(i,1);
177
const int n3 = nspecial(i,2);
179
for (int k = 0; k < n3; k++) {
180
if (special(i,k) == tag(j)) {
182
if (special_flag[1] == 0) return -1;
183
else if (special_flag[1] == 1) return 0;
186
if (special_flag[2] == 0) return -1;
187
else if (special_flag[2] == 1) return 0;
190
if (special_flag[3] == 0) return -1;
191
else if (special_flag[3] == 1) return 0;
199
/* ---------------------------------------------------------------------- */
201
template<class Device>
202
KOKKOS_INLINE_FUNCTION
203
int NeighborKokkosExecute<Device>::exclusion(const int &i,const int &j,
204
const int &itype,const int &jtype) const
208
if (nex_type && ex_type(itype,jtype)) return 1;
211
for (m = 0; m < nex_group; m++) {
212
if (mask(i) & ex1_bit(m) && mask(j) & ex2_bit(m)) return 1;
213
if (mask(i) & ex2_bit(m) && mask(j) & ex1_bit(m)) return 1;
218
for (m = 0; m < nex_mol; m++)
219
if (mask(i) & ex_mol_bit(m) && mask(j) & ex_mol_bit(m) &&
220
molecule(i) == molecule(j)) return 1;
226
/* ---------------------------------------------------------------------- */
228
template<class Device> template<int HalfNeigh,int GhostNewton>
229
void NeighborKokkosExecute<Device>::
230
build_Item(const int &i) const
232
/* if necessary, goto next page and add pages */
236
if (molecular == 2) moltemplate = 1;
237
else moltemplate = 0;
238
// get subview of neighbors of i
240
const AtomNeighbors neighbors_i = neigh_list.get_neighbors(i);
241
const X_FLOAT xtmp = x(i, 0);
242
const X_FLOAT ytmp = x(i, 1);
243
const X_FLOAT ztmp = x(i, 2);
244
const int itype = type(i);
246
const int ibin = coord2bin(xtmp, ytmp, ztmp);
248
const int nstencil = neigh_list.nstencil;
249
const typename ArrayTypes<Device>::t_int_1d_const_um stencil
250
= neigh_list.d_stencil;
252
// loop over all bins in neighborhood (includes ibin)
254
for(int m = 0; m < c_bincount(ibin); m++) {
255
const int j = c_bins(ibin,m);
256
const int jtype = type(j);
258
//for same bin as atom i skip j if i==j and skip atoms "below and to the left" if using HalfNeighborlists
259
if((j == i) || (HalfNeigh && !GhostNewton && (j < i)) ||
260
(HalfNeigh && GhostNewton && ((j < i) || ((j >= nlocal) &&
261
((x(j, 2) < ztmp) || (x(j, 2) == ztmp && x(j, 1) < ytmp) ||
262
(x(j, 2) == ztmp && x(j, 1) == ytmp && x(j, 0) < xtmp)))))
264
if(exclude && exclusion(i,j,itype,jtype)) continue;
266
const X_FLOAT delx = xtmp - x(j, 0);
267
const X_FLOAT dely = ytmp - x(j, 1);
268
const X_FLOAT delz = ztmp - x(j, 2);
269
const X_FLOAT rsq = delx * delx + dely * dely + delz * delz;
270
if(rsq <= cutneighsq(itype,jtype)) {
273
which = find_special(i,j);
274
/* else if (imol >= 0) */
275
/* which = find_special(onemols[imol]->special[iatom], */
276
/* onemols[imol]->nspecial[iatom], */
277
/* tag[j]-tagprev); */
278
/* else which = 0; */
280
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
281
}else if (minimum_image_check(delx,dely,delz)){
282
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
284
else if (which > 0) {
285
if(n<neigh_list.maxneighs) neighbors_i(n++) = j ^ (which << SBBITS);
288
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
293
for(int k = 0; k < nstencil; k++) {
294
const int jbin = ibin + stencil[k];
295
// get subview of jbin
296
if(HalfNeigh&&(ibin==jbin)) continue;
297
//const ArrayTypes<Device>::t_int_1d_const_um =Kokkos::subview<t_int_1d_const_um>(bins,jbin,ALL);
298
for(int m = 0; m < c_bincount(jbin); m++) {
299
const int j = c_bins(jbin,m);
300
const int jtype = type(j);
302
if(HalfNeigh && !GhostNewton && (j < i)) continue;
303
if(!HalfNeigh && j==i) continue;
304
if(exclude && exclusion(i,j,itype,jtype)) continue;
306
const X_FLOAT delx = xtmp - x(j, 0);
307
const X_FLOAT dely = ytmp - x(j, 1);
308
const X_FLOAT delz = ztmp - x(j, 2);
309
const X_FLOAT rsq = delx * delx + dely * dely + delz * delz;
311
if(rsq <= cutneighsq(itype,jtype)) {
314
which = find_special(i,j);
315
/* else if (imol >= 0) */
316
/* which = find_special(onemols[imol]->special[iatom], */
317
/* onemols[imol]->nspecial[iatom], */
318
/* tag[j]-tagprev); */
319
/* else which = 0; */
321
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
322
}else if (minimum_image_check(delx,dely,delz)){
323
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
325
else if (which > 0) {
326
if(n<neigh_list.maxneighs) neighbors_i(n++) = j ^ (which << SBBITS);
329
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
336
neigh_list.d_numneigh(i) = n;
338
if(n >= neigh_list.maxneighs) {
341
if(n >= new_maxneighs()) new_maxneighs() = n;
343
neigh_list.d_ilist(i) = i;
346
#ifdef KOKKOS_HAVE_CUDA
347
extern __shared__ X_FLOAT sharedmem[];
349
/* ---------------------------------------------------------------------- */
351
template<class DeviceType> template<int HalfNeigh,int GhostNewton>
353
void NeighborKokkosExecute<DeviceType>::build_ItemCuda(typename Kokkos::TeamPolicy<DeviceType>::member_type dev) const
355
/* loop over atoms in i's bin,
357
const int atoms_per_bin = c_bins.dimension_1();
358
const int BINS_PER_TEAM = dev.team_size()/atoms_per_bin<1?1:dev.team_size()/atoms_per_bin;
359
const int TEAMS_PER_BIN = atoms_per_bin/dev.team_size()<1?1:atoms_per_bin/dev.team_size();
360
const int MY_BIN = dev.team_rank()/atoms_per_bin;
362
const int ibin = dev.league_rank()*BINS_PER_TEAM+MY_BIN;
364
if(ibin >=c_bincount.dimension_0()) return;
365
X_FLOAT* other_x = sharedmem;
366
other_x = other_x + 5*atoms_per_bin*MY_BIN;
368
int* other_id = (int*) &other_x[4 * atoms_per_bin];
370
int bincount_current = c_bincount[ibin];
372
for(int kk = 0; kk < TEAMS_PER_BIN; kk++) {
373
const int MY_II = dev.team_rank()%atoms_per_bin+kk*dev.team_size();
374
const int i = MY_II < bincount_current ? c_bins(ibin, MY_II) : -1;
375
/* if necessary, goto next page and add pages */
383
const AtomNeighbors neighbors_i = neigh_list.get_neighbors((i>=0&&i<nlocal)?i:0);
390
other_x[MY_II] = xtmp;
391
other_x[MY_II + atoms_per_bin] = ytmp;
392
other_x[MY_II + 2 * atoms_per_bin] = ztmp;
393
other_x[MY_II + 3 * atoms_per_bin] = itype;
396
int test = (__syncthreads_count(i >= 0 && i <= nlocal) == 0);
400
if(i >= 0 && i < nlocal) {
402
for(int m = 0; m < bincount_current; m++) {
404
const int jtype = other_x[m + 3 * atoms_per_bin];
406
//for same bin as atom i skip j if i==j and skip atoms "below and to the left" if using halfneighborlists
408
(HalfNeigh && !GhostNewton && (j < i)) ||
409
(HalfNeigh && GhostNewton &&
411
((j >= nlocal) && ((x(j, 2) < ztmp) || (x(j, 2) == ztmp && x(j, 1) < ytmp) ||
412
(x(j, 2) == ztmp && x(j, 1) == ytmp && x(j, 0) < xtmp)))))
414
if(exclude && exclusion(i,j,itype,jtype)) continue;
415
const X_FLOAT delx = xtmp - other_x[m];
416
const X_FLOAT dely = ytmp - other_x[m + atoms_per_bin];
417
const X_FLOAT delz = ztmp - other_x[m + 2 * atoms_per_bin];
418
const X_FLOAT rsq = delx * delx + dely * dely + delz * delz;
420
if(rsq <= cutneighsq(itype,jtype)) {
424
which = find_special(i,j);
425
/* else if (imol >= 0) */
426
/* which = find_special(onemols[imol]->special[iatom], */
427
/* onemols[imol]->nspecial[iatom], */
428
/* tag[j]-tagprev); */
429
/* else which = 0; */
431
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
432
}else if (minimum_image_check(delx,dely,delz)){
433
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
435
else if (which > 0) {
436
if(n<neigh_list.maxneighs) neighbors_i(n++) = j ^ (which << SBBITS);
439
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
447
const int nstencil = neigh_list.nstencil;
448
const typename ArrayTypes<DeviceType>::t_int_1d_const_um stencil
449
= neigh_list.d_stencil;
450
for(int k = 0; k < nstencil; k++) {
451
const int jbin = ibin + stencil[k];
453
if(ibin == jbin) continue;
455
bincount_current = c_bincount[jbin];
456
int j = MY_II < bincount_current ? c_bins(jbin, MY_II) : -1;
459
other_x[MY_II] = x(j, 0);
460
other_x[MY_II + atoms_per_bin] = x(j, 1);
461
other_x[MY_II + 2 * atoms_per_bin] = x(j, 2);
462
other_x[MY_II + 3 * atoms_per_bin] = type(j);
469
if(i >= 0 && i < nlocal) {
471
for(int m = 0; m < bincount_current; m++) {
472
const int j = other_id[m];
473
const int jtype = other_x[m + 3 * atoms_per_bin];
475
//if(HalfNeigh && (j < i)) continue;
476
if(HalfNeigh && !GhostNewton && (j < i)) continue;
477
if(!HalfNeigh && j==i) continue;
478
if(exclude && exclusion(i,j,itype,jtype)) continue;
480
const X_FLOAT delx = xtmp - other_x[m];
481
const X_FLOAT dely = ytmp - other_x[m + atoms_per_bin];
482
const X_FLOAT delz = ztmp - other_x[m + 2 * atoms_per_bin];
483
const X_FLOAT rsq = delx * delx + dely * dely + delz * delz;
485
if(rsq <= cutneighsq(itype,jtype)) {
489
which = find_special(i,j);
490
/* else if (imol >= 0) */
491
/* which = find_special(onemols[imol]->special[iatom], */
492
/* onemols[imol]->nspecial[iatom], */
493
/* tag[j]-tagprev); */
494
/* else which = 0; */
496
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
497
}else if (minimum_image_check(delx,dely,delz)){
498
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
500
else if (which > 0) {
501
if(n<neigh_list.maxneighs) neighbors_i(n++) = j ^ (which << SBBITS);
504
if(n<neigh_list.maxneighs) neighbors_i(n++) = j;
513
if(i >= 0 && i < nlocal) {
514
neigh_list.d_numneigh(i) = n;
515
neigh_list.d_ilist(i) = i;
518
if(n >= neigh_list.maxneighs) {
521
if(n >= new_maxneighs()) new_maxneighs() = n;
527
template<class DeviceType>
528
void NeighborKokkos::full_bin_cluster_kokkos(NeighListKokkos<DeviceType> *list)
530
const int nall = includegroup?atom->nfirst:atom->nlocal;
533
NeighborKokkosExecute<DeviceType>
535
k_cutneighsq.view<DeviceType>(),
536
k_bincount.view<DeviceType>(),
537
k_bins.view<DeviceType>(),nall,
538
atomKK->k_x.view<DeviceType>(),
539
atomKK->k_type.view<DeviceType>(),
540
atomKK->k_mask.view<DeviceType>(),
541
atomKK->k_molecule.view<DeviceType>(),
542
atomKK->k_tag.view<DeviceType>(),
543
atomKK->k_special.view<DeviceType>(),
544
atomKK->k_nspecial.view<DeviceType>(),
546
nbinx,nbiny,nbinz,mbinx,mbiny,mbinz,mbinxlo,mbinylo,mbinzlo,
547
bininvx,bininvy,bininvz,
548
exclude, nex_type,maxex_type,
549
k_ex1_type.view<DeviceType>(),
550
k_ex2_type.view<DeviceType>(),
551
k_ex_type.view<DeviceType>(),
552
nex_group,maxex_group,
553
k_ex1_group.view<DeviceType>(),
554
k_ex2_group.view<DeviceType>(),
555
k_ex1_bit.view<DeviceType>(),
556
k_ex2_bit.view<DeviceType>(),
558
k_ex_mol_group.view<DeviceType>(),
559
k_ex_mol_bit.view<DeviceType>(),
561
domain->xperiodic,domain->yperiodic,domain->zperiodic,
562
domain->xprd_half,domain->yprd_half,domain->zprd_half);
564
k_cutneighsq.sync<DeviceType>();
565
k_ex1_type.sync<DeviceType>();
566
k_ex2_type.sync<DeviceType>();
567
k_ex_type.sync<DeviceType>();
568
k_ex1_group.sync<DeviceType>();
569
k_ex2_group.sync<DeviceType>();
570
k_ex1_bit.sync<DeviceType>();
571
k_ex2_bit.sync<DeviceType>();
572
k_ex_mol_group.sync<DeviceType>();
573
k_ex_mol_bit.sync<DeviceType>();
575
data.special_flag[0] = special_flag[0];
576
data.special_flag[1] = special_flag[1];
577
data.special_flag[2] = special_flag[2];
578
data.special_flag[3] = special_flag[3];
580
atomKK->sync(Device,X_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK);
581
Kokkos::deep_copy(list->d_stencil,list->h_stencil);
584
while(data.h_resize() > 0) {
586
deep_copy(data.resize, data.h_resize);
588
MemsetZeroFunctor<DeviceType> f_zero;
589
f_zero.ptr = (void*) k_bincount.view<DeviceType>().ptr_on_device();
590
Kokkos::parallel_for(mbins, f_zero);
593
NeighborKokkosBinAtomsFunctor<DeviceType> f(data);
595
Kokkos::parallel_for(atom->nlocal+atom->nghost, f);
598
deep_copy(data.h_resize, data.resize);
599
if(data.h_resize()) {
602
k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin);
603
data.bins = k_bins.view<DeviceType>();
604
data.c_bins = data.bins;
608
if(list->d_neighbors.dimension_0()<nall) {
609
list->d_neighbors = typename ArrayTypes<DeviceType>::t_neighbors_2d("neighbors", nall*1.1, list->maxneighs);
610
list->d_numneigh = typename ArrayTypes<DeviceType>::t_int_1d("numneigh", nall*1.1);
611
data.neigh_list.d_neighbors = list->d_neighbors;
612
data.neigh_list.d_numneigh = list->d_numneigh;
615
while(data.h_resize()) {
616
data.h_new_maxneighs() = list->maxneighs;
619
Kokkos::deep_copy(data.resize, data.h_resize);
620
Kokkos::deep_copy(data.new_maxneighs, data.h_new_maxneighs);
621
#ifdef KOKKOS_HAVE_CUDA
622
#define BINS_PER_BLOCK 2
623
const int factor = atoms_per_bin<64?2:1;
624
Kokkos::TeamPolicy<DeviceType> config((mbins+factor-1)/factor,atoms_per_bin*factor);
626
const int factor = 1;
630
NeighborClusterKokkosBuildFunctor<DeviceType,NeighClusterSize> f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor);
631
//#ifdef KOKKOS_HAVE_CUDA
632
// Kokkos::parallel_for(config, f);
634
Kokkos::parallel_for(nall, f);
637
NeighborClusterKokkosBuildFunctor<DeviceType,NeighClusterSize> f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor);
638
//#ifdef KOKKOS_HAVE_CUDA
639
// Kokkos::parallel_for(config, f);
641
Kokkos::parallel_for(nall, f);
645
deep_copy(data.h_resize, data.resize);
647
if(data.h_resize()) {
648
deep_copy(data.h_new_maxneighs, data.new_maxneighs);
649
list->maxneighs = data.h_new_maxneighs() * 1.2;
650
list->d_neighbors = typename ArrayTypes<DeviceType>::t_neighbors_2d("neighbors", list->d_neighbors.dimension_0(), list->maxneighs);
651
data.neigh_list.d_neighbors = list->d_neighbors;
652
data.neigh_list.maxneighs = list->maxneighs;
661
/* ---------------------------------------------------------------------- */
663
template<class Device> template<int ClusterSize>
664
void NeighborKokkosExecute<Device>::
665
build_cluster_Item(const int &i) const
667
/* if necessary, goto next page and add pages */
670
// get subview of neighbors of i
672
const AtomNeighbors neighbors_i = neigh_list.get_neighbors(i);
673
const X_FLOAT xtmp = x(i, 0);
674
const X_FLOAT ytmp = x(i, 1);
675
const X_FLOAT ztmp = x(i, 2);
676
const int itype = type(i);
678
const int ibin = coord2bin(xtmp, ytmp, ztmp);
680
const int nstencil = neigh_list.nstencil;
681
const typename ArrayTypes<Device>::t_int_1d_const_um stencil
682
= neigh_list.d_stencil;
684
for(int k = 0; k < nstencil; k++) {
685
const int jbin = ibin + stencil[k];
686
for(int m = 0; m < c_bincount(jbin); m++) {
687
const int j = c_bins(jbin,m);
689
for(int k = 0; k< (n<neigh_list.maxneighs?n:neigh_list.maxneighs); k++)
690
if((j-(j%ClusterSize)) == neighbors_i(k)) {skip=true;};//{m += ClusterSize - j&(ClusterSize-1)-1; skip=true;}
693
const int jtype = type(j);
695
const X_FLOAT delx = xtmp - x(j, 0);
696
const X_FLOAT dely = ytmp - x(j, 1);
697
const X_FLOAT delz = ztmp - x(j, 2);
698
const X_FLOAT rsq = delx * delx + dely * dely + delz * delz;
700
if(rsq <= cutneighsq(itype,jtype)) {
701
if(n<neigh_list.maxneighs) neighbors_i(n) = (j-(j%ClusterSize));
703
//m += ClusterSize - j&(ClusterSize-1)-1;
710
neigh_list.d_numneigh(i) = n;
712
if(n >= neigh_list.maxneighs) {
715
if(n >= new_maxneighs()) new_maxneighs() = n;
717
neigh_list.d_ilist(i) = i;