From c9c2ae6c613486bbc2b78a19df4e77691197eb32 Mon Sep 17 00:00:00 2001 From: Steve Plimpton Date: Wed, 7 Sep 2016 13:42:58 -0600 Subject: [PATCH 01/22] new neighbor list changes --- src/Make.sh | 17 +- src/Purge.list | 33 + .../#npair_half_bin_newton_ssa.cpp#} | 241 +- src/USER-DPD/fix_shardlow.cpp | 1 - src/USER-DPD/npair_half_bin_newton_ssa.cpp | 311 ++ src/USER-DPD/npair_half_bin_newton_ssa.h | 43 + src/USER-DPD/npair_halffull_newton_ssa.cpp | 132 + src/USER-DPD/npair_halffull_newton_ssa.h | 44 + .../nstencil_half_bin_2d_newton_ssa.cpp | 64 + .../nstencil_half_bin_2d_newton_ssa.h | 43 + .../nstencil_half_bin_3d_newton_ssa.cpp | 74 + .../nstencil_half_bin_3d_newton_ssa.h | 43 + src/USER-INTEL/Install.sh | 16 +- src/USER-INTEL/fix_intel.cpp | 2 - src/USER-INTEL/intel_buffers.cpp | 107 +- src/USER-INTEL/intel_buffers.h | 70 +- src/USER-INTEL/nbin_intel.cpp | 253 ++ src/USER-INTEL/nbin_intel.h | 69 + src/USER-INTEL/neigh_half_bin_intel.cpp | 2455 ---------------- src/USER-INTEL/npair_full_bin_intel.cpp | 552 ++++ src/USER-INTEL/npair_full_bin_intel.h | 51 + .../npair_half_bin_newtoff_intel.cpp | 451 +++ src/USER-INTEL/npair_half_bin_newtoff_intel.h | 52 + .../npair_half_bin_newton_intel.cpp | 610 ++++ src/USER-INTEL/npair_half_bin_newton_intel.h | 51 + .../npair_half_bin_newton_tri_intel.cpp | 513 ++++ .../npair_half_bin_newton_tri_intel.h | 51 + src/USER-INTEL/npair_intel.cpp | 69 + src/USER-INTEL/npair_intel.h | 117 + src/USER-OMP/neigh_full_omp.cpp | 621 ---- src/USER-OMP/neigh_gran_omp.cpp | 618 ---- src/USER-OMP/neigh_half_bin_omp.cpp | 559 ---- src/USER-OMP/neigh_half_multi_omp.cpp | 435 --- src/USER-OMP/neigh_half_nsq_omp.cpp | 376 --- src/USER-OMP/neigh_respa_omp.cpp | 972 ------- src/USER-OMP/npair_full_bin_ghost_omp.cpp | 166 ++ src/USER-OMP/npair_full_bin_ghost_omp.h | 44 + src/USER-OMP/npair_full_bin_omp.cpp | 135 + src/USER-OMP/npair_full_bin_omp.h | 44 + src/USER-OMP/npair_full_multi_omp.cpp | 143 + src/USER-OMP/npair_full_multi_omp.h | 44 + src/USER-OMP/npair_full_nsq_ghost_omp.cpp | 148 + src/USER-OMP/npair_full_nsq_ghost_omp.h | 44 + src/USER-OMP/npair_full_nsq_omp.cpp | 134 + src/USER-OMP/npair_full_nsq_omp.h | 44 + .../npair_half_bin_newtoff_ghost_omp.cpp | 173 ++ .../npair_half_bin_newtoff_ghost_omp.h | 44 + src/USER-OMP/npair_half_bin_newtoff_omp.cpp | 138 + src/USER-OMP/npair_half_bin_newtoff_omp.h | 43 + src/USER-OMP/npair_half_bin_newton_omp.cpp | 172 ++ src/USER-OMP/npair_half_bin_newton_omp.h | 43 + .../npair_half_bin_newton_tri_omp.cpp | 144 + src/USER-OMP/npair_half_bin_newton_tri_omp.h | 43 + src/USER-OMP/npair_half_multi_newtoff_omp.cpp | 145 + src/USER-OMP/npair_half_multi_newtoff_omp.h | 43 + src/USER-OMP/npair_half_multi_newton_omp.cpp | 178 ++ src/USER-OMP/npair_half_multi_newton_omp.h | 43 + .../npair_half_multi_newton_tri_omp.cpp | 154 + .../npair_half_multi_newton_tri_omp.h | 43 + .../npair_half_nsq_newtoff_ghost_omp.cpp | 157 + .../npair_half_nsq_newtoff_ghost_omp.h | 44 + src/USER-OMP/npair_half_nsq_newtoff_omp.cpp | 133 + src/USER-OMP/npair_half_nsq_newtoff_omp.h | 43 + src/USER-OMP/npair_half_nsq_newton_omp.cpp | 151 + src/USER-OMP/npair_half_nsq_newton_omp.h | 43 + .../npair_half_respa_bin_newtoff_omp.cpp | 204 ++ .../npair_half_respa_bin_newtoff_omp.h | 44 + .../npair_half_respa_bin_newton_omp.cpp | 250 ++ .../npair_half_respa_bin_newton_omp.h | 43 + .../npair_half_respa_bin_newton_tri_omp.cpp | 211 ++ .../npair_half_respa_bin_newton_tri_omp.h | 43 + .../npair_half_respa_nsq_newtoff_omp.cpp | 198 ++ .../npair_half_respa_nsq_newtoff_omp.h | 44 + .../npair_half_respa_nsq_newton_omp.cpp | 217 ++ .../npair_half_respa_nsq_newton_omp.h | 44 + .../npair_half_size_bin_newtoff_omp.cpp | 179 ++ .../npair_half_size_bin_newtoff_omp.h | 44 + .../npair_half_size_bin_newton_omp.cpp | 227 ++ src/USER-OMP/npair_half_size_bin_newton_omp.h | 43 + .../npair_half_size_bin_newton_tri_omp.cpp | 121 + .../npair_half_size_bin_newton_tri_omp.h | 43 + .../npair_half_size_nsq_newtoff_omp.cpp | 177 ++ .../npair_half_size_nsq_newtoff_omp.h | 44 + .../npair_half_size_nsq_newton_omp.cpp | 195 ++ src/USER-OMP/npair_half_size_nsq_newton_omp.h | 44 + src/USER-OMP/npair_halffull_newtoff_omp.cpp | 91 + src/USER-OMP/npair_halffull_newtoff_omp.h | 44 + ..._omp.cpp => npair_halffull_newton_omp.cpp} | 77 +- src/USER-OMP/npair_halffull_newton_omp.h | 44 + src/USER-OMP/{neighbor_omp.h => npair_omp.h} | 19 +- src/accelerator_intel.h | 68 - src/nbin.cpp | 143 + src/nbin.h | 78 + src/nbin_standard.cpp | 232 ++ src/nbin_standard.h | 44 + src/neigh_bond.cpp | 1028 ------- src/neigh_bond.h | 88 - src/neigh_derive.cpp | 845 ------ src/neigh_full.cpp | 590 ---- src/neigh_gran.cpp | 839 ------ src/neigh_half_bin.cpp | 534 ---- src/neigh_half_multi.cpp | 415 --- src/neigh_half_multi.h | 22 - src/neigh_half_nsq.cpp | 360 --- src/neigh_half_nsq.h | 22 - src/neigh_list.cpp | 268 +- src/neigh_list.h | 49 +- src/neigh_request.cpp | 18 +- src/neigh_request.h | 26 +- src/neigh_respa.cpp | 928 ------ src/neigh_respa.h | 22 - src/neigh_shardlow.h | 22 - src/neigh_stencil.cpp | 536 ---- src/neighbor.cpp | 2587 ++++++++--------- src/neighbor.h | 406 +-- src/npair.cpp | 258 ++ src/npair.h | 146 + src/npair_copy.cpp | 46 + src/{neigh_gran.h => npair_copy.h} | 33 +- src/npair_full_bin.cpp | 125 + src/npair_full_bin.h | 43 + src/npair_full_bin_ghost.cpp | 156 + src/npair_full_bin_ghost.h | 44 + src/npair_full_multi.cpp | 132 + src/npair_full_multi.h | 43 + src/npair_full_nsq.cpp | 125 + src/npair_full_nsq.h | 43 + src/npair_full_nsq_ghost.cpp | 138 + src/npair_full_nsq_ghost.h | 44 + src/npair_half_bin_newtoff.cpp | 129 + src/npair_half_bin_newtoff.h | 43 + src/npair_half_bin_newtoff_ghost.cpp | 162 ++ src/npair_half_bin_newtoff_ghost.h | 43 + src/npair_half_bin_newton.cpp | 161 + src/npair_half_bin_newton.h | 43 + src/npair_half_bin_newton_ssa.cpp | 311 ++ src/npair_half_bin_newton_ssa.h | 43 + src/npair_half_bin_newton_tri.cpp | 134 + src/npair_half_bin_newton_tri.h | 43 + src/npair_half_multi_newtoff.cpp | 135 + src/npair_half_multi_newtoff.h | 43 + src/npair_half_multi_newton.cpp | 168 ++ src/npair_half_multi_newton.h | 43 + src/npair_half_multi_newton_tri.cpp | 143 + src/npair_half_multi_newton_tri.h | 43 + src/npair_half_nsq_newtoff.cpp | 125 + src/npair_half_nsq_newtoff.h | 43 + src/npair_half_nsq_newtoff_ghost.cpp | 150 + src/npair_half_nsq_newtoff_ghost.h | 43 + src/npair_half_nsq_newton.cpp | 142 + src/npair_half_nsq_newton.h | 43 + src/npair_half_respa_bin_newtoff.cpp | 190 ++ src/npair_half_respa_bin_newtoff.h | 43 + src/npair_half_respa_bin_newton.cpp | 236 ++ src/npair_half_respa_bin_newton.h | 43 + src/npair_half_respa_bin_newton_tri.cpp | 198 ++ src/npair_half_respa_bin_newton_tri.h | 43 + src/npair_half_respa_nsq_newtoff.cpp | 185 ++ src/npair_half_respa_nsq_newtoff.h | 43 + src/npair_half_respa_nsq_newton.cpp | 205 ++ src/npair_half_respa_nsq_newton.h | 43 + src/npair_half_size_bin_newtoff.cpp | 171 ++ src/npair_half_size_bin_newtoff.h | 43 + src/npair_half_size_bin_newton.cpp | 215 ++ src/npair_half_size_bin_newton.h | 43 + src/npair_half_size_bin_newton_tri.cpp | 180 ++ src/npair_half_size_bin_newton_tri.h | 43 + src/npair_half_size_nsq_newtoff.cpp | 169 ++ src/npair_half_size_nsq_newtoff.h | 43 + src/npair_half_size_nsq_newton.cpp | 187 ++ src/npair_half_size_nsq_newton.h | 43 + src/npair_halffull_newtoff.cpp | 82 + src/npair_halffull_newtoff.h | 44 + src/npair_halffull_newton.cpp | 99 + src/npair_halffull_newton.h | 44 + src/npair_halffull_newton_ssa.cpp | 132 + src/npair_halffull_newton_ssa.h | 44 + src/npair_skip.cpp | 103 + src/npair_skip.h | 44 + src/npair_skip_respa.cpp | 169 ++ src/npair_skip_respa.h | 45 + src/npair_skip_size.cpp | 161 + src/npair_skip_size.h | 44 + src/npair_skip_size_off2on.cpp | 168 ++ src/npair_skip_size_off2on.h | 45 + src/npair_skip_size_off2on_oneside.cpp | 223 ++ src/npair_skip_size_off2on_oneside.h | 45 + src/nstencil.cpp | 230 ++ src/nstencil.h | 84 + src/nstencil_full_bin_2d.cpp | 38 + src/nstencil_full_bin_2d.h | 44 + src/nstencil_full_bin_3d.cpp | 39 + src/nstencil_full_bin_3d.h | 44 + src/nstencil_full_ghost_bin_2d.cpp | 45 + src/nstencil_full_ghost_bin_2d.h | 44 + src/nstencil_full_ghost_bin_3d.cpp | 46 + src/nstencil_full_ghost_bin_3d.h | 44 + src/nstencil_full_multi_2d.cpp | 52 + src/nstencil_full_multi_2d.h | 44 + src/nstencil_full_multi_3d.cpp | 53 + src/nstencil_full_multi_3d.h | 44 + src/nstencil_half_bin_2d_newtoff.cpp | 39 + src/nstencil_half_bin_2d_newtoff.h | 43 + src/nstencil_half_bin_2d_newton.cpp | 39 + src/nstencil_half_bin_2d_newton.h | 43 + src/nstencil_half_bin_2d_newton_ssa.cpp | 64 + src/nstencil_half_bin_2d_newton_ssa.h | 43 + src/nstencil_half_bin_2d_newton_tri.cpp | 39 + src/nstencil_half_bin_2d_newton_tri.h | 43 + src/nstencil_half_bin_3d_newtoff.cpp | 40 + src/nstencil_half_bin_3d_newtoff.h | 43 + src/nstencil_half_bin_3d_newton.cpp | 40 + src/nstencil_half_bin_3d_newton.h | 43 + src/nstencil_half_bin_3d_newton_ssa.cpp | 74 + src/nstencil_half_bin_3d_newton_ssa.h | 43 + src/nstencil_half_bin_3d_newton_tri.cpp | 40 + src/nstencil_half_bin_3d_newton_tri.h | 43 + src/nstencil_half_ghost_bin_2d_newtoff.cpp | 46 + src/nstencil_half_ghost_bin_2d_newtoff.h | 44 + src/nstencil_half_ghost_bin_3d_newtoff.cpp | 47 + src/nstencil_half_ghost_bin_3d_newtoff.h | 44 + src/nstencil_half_multi_2d_newtoff.cpp | 53 + src/nstencil_half_multi_2d_newtoff.h | 43 + src/nstencil_half_multi_2d_newton.cpp | 54 + src/nstencil_half_multi_2d_newton.h | 43 + src/nstencil_half_multi_2d_newton_tri.cpp | 53 + src/nstencil_half_multi_2d_newton_tri.h | 43 + src/nstencil_half_multi_3d_newtoff.cpp | 54 + src/nstencil_half_multi_3d_newtoff.h | 43 + src/nstencil_half_multi_3d_newton.cpp | 55 + src/nstencil_half_multi_3d_newton.h | 43 + src/nstencil_half_multi_3d_newton_tri.cpp | 54 + src/nstencil_half_multi_3d_newton_tri.h | 43 + src/ntopo.cpp | 218 ++ src/ntopo.h | 56 + src/ntopo_angle_all.cpp | 99 + src/{neigh_full.h => ntopo_angle_all.h} | 31 +- src/ntopo_angle_partial.cpp | 100 + src/ntopo_angle_partial.h | 41 + src/ntopo_angle_template.cpp | 119 + src/ntopo_angle_template.h | 41 + src/ntopo_bond_all.cpp | 91 + src/{neigh_derive.h => ntopo_bond_all.h} | 31 +- src/ntopo_bond_partial.cpp | 92 + ...{neigh_half_bin.h => ntopo_bond_partial.h} | 31 +- src/ntopo_bond_template.cpp | 109 + src/ntopo_bond_template.h | 41 + src/ntopo_dihedral_all.cpp | 106 + src/ntopo_dihedral_all.h | 41 + src/ntopo_dihedral_partial.cpp | 108 + src/ntopo_dihedral_partial.h | 41 + src/ntopo_dihedral_template.cpp | 127 + src/ntopo_dihedral_template.h | 41 + src/ntopo_improper_all.cpp | 106 + src/ntopo_improper_all.h | 41 + src/ntopo_improper_partial.cpp | 108 + src/ntopo_improper_partial.h | 41 + src/ntopo_improper_template.cpp | 127 + src/ntopo_improper_template.h | 41 + 259 files changed, 23076 insertions(+), 14650 deletions(-) rename src/{neigh_shardlow.cpp => USER-DPD/#npair_half_bin_newton_ssa.cpp#} (60%) create mode 100644 src/USER-DPD/npair_half_bin_newton_ssa.cpp create mode 100644 src/USER-DPD/npair_half_bin_newton_ssa.h create mode 100644 src/USER-DPD/npair_halffull_newton_ssa.cpp create mode 100644 src/USER-DPD/npair_halffull_newton_ssa.h create mode 100644 src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp create mode 100644 src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h create mode 100644 src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp create mode 100644 src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h create mode 100644 src/USER-INTEL/nbin_intel.cpp create mode 100644 src/USER-INTEL/nbin_intel.h delete mode 100644 src/USER-INTEL/neigh_half_bin_intel.cpp create mode 100644 src/USER-INTEL/npair_full_bin_intel.cpp create mode 100644 src/USER-INTEL/npair_full_bin_intel.h create mode 100644 src/USER-INTEL/npair_half_bin_newtoff_intel.cpp create mode 100644 src/USER-INTEL/npair_half_bin_newtoff_intel.h create mode 100644 src/USER-INTEL/npair_half_bin_newton_intel.cpp create mode 100644 src/USER-INTEL/npair_half_bin_newton_intel.h create mode 100644 src/USER-INTEL/npair_half_bin_newton_tri_intel.cpp create mode 100644 src/USER-INTEL/npair_half_bin_newton_tri_intel.h create mode 100644 src/USER-INTEL/npair_intel.cpp create mode 100644 src/USER-INTEL/npair_intel.h delete mode 100644 src/USER-OMP/neigh_full_omp.cpp delete mode 100644 src/USER-OMP/neigh_gran_omp.cpp delete mode 100644 src/USER-OMP/neigh_half_bin_omp.cpp delete mode 100644 src/USER-OMP/neigh_half_multi_omp.cpp delete mode 100644 src/USER-OMP/neigh_half_nsq_omp.cpp delete mode 100644 src/USER-OMP/neigh_respa_omp.cpp create mode 100644 src/USER-OMP/npair_full_bin_ghost_omp.cpp create mode 100644 src/USER-OMP/npair_full_bin_ghost_omp.h create mode 100644 src/USER-OMP/npair_full_bin_omp.cpp create mode 100644 src/USER-OMP/npair_full_bin_omp.h create mode 100644 src/USER-OMP/npair_full_multi_omp.cpp create mode 100644 src/USER-OMP/npair_full_multi_omp.h create mode 100644 src/USER-OMP/npair_full_nsq_ghost_omp.cpp create mode 100644 src/USER-OMP/npair_full_nsq_ghost_omp.h create mode 100644 src/USER-OMP/npair_full_nsq_omp.cpp create mode 100644 src/USER-OMP/npair_full_nsq_omp.h create mode 100644 src/USER-OMP/npair_half_bin_newtoff_ghost_omp.cpp create mode 100644 src/USER-OMP/npair_half_bin_newtoff_ghost_omp.h create mode 100644 src/USER-OMP/npair_half_bin_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_half_bin_newtoff_omp.h create mode 100644 src/USER-OMP/npair_half_bin_newton_omp.cpp create mode 100644 src/USER-OMP/npair_half_bin_newton_omp.h create mode 100644 src/USER-OMP/npair_half_bin_newton_tri_omp.cpp create mode 100644 src/USER-OMP/npair_half_bin_newton_tri_omp.h create mode 100644 src/USER-OMP/npair_half_multi_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_half_multi_newtoff_omp.h create mode 100644 src/USER-OMP/npair_half_multi_newton_omp.cpp create mode 100644 src/USER-OMP/npair_half_multi_newton_omp.h create mode 100644 src/USER-OMP/npair_half_multi_newton_tri_omp.cpp create mode 100644 src/USER-OMP/npair_half_multi_newton_tri_omp.h create mode 100644 src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.cpp create mode 100644 src/USER-OMP/npair_half_nsq_newtoff_ghost_omp.h create mode 100644 src/USER-OMP/npair_half_nsq_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_half_nsq_newtoff_omp.h create mode 100644 src/USER-OMP/npair_half_nsq_newton_omp.cpp create mode 100644 src/USER-OMP/npair_half_nsq_newton_omp.h create mode 100644 src/USER-OMP/npair_half_respa_bin_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_half_respa_bin_newtoff_omp.h create mode 100644 src/USER-OMP/npair_half_respa_bin_newton_omp.cpp create mode 100644 src/USER-OMP/npair_half_respa_bin_newton_omp.h create mode 100644 src/USER-OMP/npair_half_respa_bin_newton_tri_omp.cpp create mode 100644 src/USER-OMP/npair_half_respa_bin_newton_tri_omp.h create mode 100644 src/USER-OMP/npair_half_respa_nsq_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_half_respa_nsq_newtoff_omp.h create mode 100644 src/USER-OMP/npair_half_respa_nsq_newton_omp.cpp create mode 100644 src/USER-OMP/npair_half_respa_nsq_newton_omp.h create mode 100644 src/USER-OMP/npair_half_size_bin_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_half_size_bin_newtoff_omp.h create mode 100644 src/USER-OMP/npair_half_size_bin_newton_omp.cpp create mode 100644 src/USER-OMP/npair_half_size_bin_newton_omp.h create mode 100644 src/USER-OMP/npair_half_size_bin_newton_tri_omp.cpp create mode 100644 src/USER-OMP/npair_half_size_bin_newton_tri_omp.h create mode 100644 src/USER-OMP/npair_half_size_nsq_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_half_size_nsq_newtoff_omp.h create mode 100644 src/USER-OMP/npair_half_size_nsq_newton_omp.cpp create mode 100644 src/USER-OMP/npair_half_size_nsq_newton_omp.h create mode 100644 src/USER-OMP/npair_halffull_newtoff_omp.cpp create mode 100644 src/USER-OMP/npair_halffull_newtoff_omp.h rename src/USER-OMP/{neigh_derive_omp.cpp => npair_halffull_newton_omp.cpp} (61%) create mode 100644 src/USER-OMP/npair_halffull_newton_omp.h rename src/USER-OMP/{neighbor_omp.h => npair_omp.h} (81%) delete mode 100644 src/accelerator_intel.h create mode 100644 src/nbin.cpp create mode 100644 src/nbin.h create mode 100644 src/nbin_standard.cpp create mode 100644 src/nbin_standard.h delete mode 100644 src/neigh_bond.cpp delete mode 100644 src/neigh_bond.h delete mode 100644 src/neigh_derive.cpp delete mode 100644 src/neigh_full.cpp delete mode 100644 src/neigh_gran.cpp delete mode 100644 src/neigh_half_bin.cpp delete mode 100644 src/neigh_half_multi.cpp delete mode 100644 src/neigh_half_multi.h delete mode 100644 src/neigh_half_nsq.cpp delete mode 100644 src/neigh_half_nsq.h delete mode 100644 src/neigh_respa.cpp delete mode 100644 src/neigh_respa.h delete mode 100644 src/neigh_shardlow.h delete mode 100644 src/neigh_stencil.cpp create mode 100644 src/npair.cpp create mode 100644 src/npair.h create mode 100644 src/npair_copy.cpp rename src/{neigh_gran.h => npair_copy.h} (67%) create mode 100644 src/npair_full_bin.cpp create mode 100644 src/npair_full_bin.h create mode 100644 src/npair_full_bin_ghost.cpp create mode 100644 src/npair_full_bin_ghost.h create mode 100644 src/npair_full_multi.cpp create mode 100644 src/npair_full_multi.h create mode 100644 src/npair_full_nsq.cpp create mode 100644 src/npair_full_nsq.h create mode 100644 src/npair_full_nsq_ghost.cpp create mode 100644 src/npair_full_nsq_ghost.h create mode 100644 src/npair_half_bin_newtoff.cpp create mode 100644 src/npair_half_bin_newtoff.h create mode 100644 src/npair_half_bin_newtoff_ghost.cpp create mode 100644 src/npair_half_bin_newtoff_ghost.h create mode 100644 src/npair_half_bin_newton.cpp create mode 100644 src/npair_half_bin_newton.h create mode 100644 src/npair_half_bin_newton_ssa.cpp create mode 100644 src/npair_half_bin_newton_ssa.h create mode 100644 src/npair_half_bin_newton_tri.cpp create mode 100644 src/npair_half_bin_newton_tri.h create mode 100644 src/npair_half_multi_newtoff.cpp create mode 100644 src/npair_half_multi_newtoff.h create mode 100644 src/npair_half_multi_newton.cpp create mode 100644 src/npair_half_multi_newton.h create mode 100644 src/npair_half_multi_newton_tri.cpp create mode 100644 src/npair_half_multi_newton_tri.h create mode 100644 src/npair_half_nsq_newtoff.cpp create mode 100644 src/npair_half_nsq_newtoff.h create mode 100644 src/npair_half_nsq_newtoff_ghost.cpp create mode 100644 src/npair_half_nsq_newtoff_ghost.h create mode 100644 src/npair_half_nsq_newton.cpp create mode 100644 src/npair_half_nsq_newton.h create mode 100644 src/npair_half_respa_bin_newtoff.cpp create mode 100644 src/npair_half_respa_bin_newtoff.h create mode 100644 src/npair_half_respa_bin_newton.cpp create mode 100644 src/npair_half_respa_bin_newton.h create mode 100644 src/npair_half_respa_bin_newton_tri.cpp create mode 100644 src/npair_half_respa_bin_newton_tri.h create mode 100644 src/npair_half_respa_nsq_newtoff.cpp create mode 100644 src/npair_half_respa_nsq_newtoff.h create mode 100644 src/npair_half_respa_nsq_newton.cpp create mode 100644 src/npair_half_respa_nsq_newton.h create mode 100644 src/npair_half_size_bin_newtoff.cpp create mode 100644 src/npair_half_size_bin_newtoff.h create mode 100644 src/npair_half_size_bin_newton.cpp create mode 100644 src/npair_half_size_bin_newton.h create mode 100644 src/npair_half_size_bin_newton_tri.cpp create mode 100644 src/npair_half_size_bin_newton_tri.h create mode 100644 src/npair_half_size_nsq_newtoff.cpp create mode 100644 src/npair_half_size_nsq_newtoff.h create mode 100644 src/npair_half_size_nsq_newton.cpp create mode 100644 src/npair_half_size_nsq_newton.h create mode 100644 src/npair_halffull_newtoff.cpp create mode 100644 src/npair_halffull_newtoff.h create mode 100644 src/npair_halffull_newton.cpp create mode 100644 src/npair_halffull_newton.h create mode 100644 src/npair_halffull_newton_ssa.cpp create mode 100644 src/npair_halffull_newton_ssa.h create mode 100644 src/npair_skip.cpp create mode 100644 src/npair_skip.h create mode 100644 src/npair_skip_respa.cpp create mode 100644 src/npair_skip_respa.h create mode 100644 src/npair_skip_size.cpp create mode 100644 src/npair_skip_size.h create mode 100644 src/npair_skip_size_off2on.cpp create mode 100644 src/npair_skip_size_off2on.h create mode 100644 src/npair_skip_size_off2on_oneside.cpp create mode 100644 src/npair_skip_size_off2on_oneside.h create mode 100644 src/nstencil.cpp create mode 100644 src/nstencil.h create mode 100644 src/nstencil_full_bin_2d.cpp create mode 100644 src/nstencil_full_bin_2d.h create mode 100644 src/nstencil_full_bin_3d.cpp create mode 100644 src/nstencil_full_bin_3d.h create mode 100644 src/nstencil_full_ghost_bin_2d.cpp create mode 100644 src/nstencil_full_ghost_bin_2d.h create mode 100644 src/nstencil_full_ghost_bin_3d.cpp create mode 100644 src/nstencil_full_ghost_bin_3d.h create mode 100644 src/nstencil_full_multi_2d.cpp create mode 100644 src/nstencil_full_multi_2d.h create mode 100644 src/nstencil_full_multi_3d.cpp create mode 100644 src/nstencil_full_multi_3d.h create mode 100644 src/nstencil_half_bin_2d_newtoff.cpp create mode 100644 src/nstencil_half_bin_2d_newtoff.h create mode 100644 src/nstencil_half_bin_2d_newton.cpp create mode 100644 src/nstencil_half_bin_2d_newton.h create mode 100644 src/nstencil_half_bin_2d_newton_ssa.cpp create mode 100644 src/nstencil_half_bin_2d_newton_ssa.h create mode 100644 src/nstencil_half_bin_2d_newton_tri.cpp create mode 100644 src/nstencil_half_bin_2d_newton_tri.h create mode 100644 src/nstencil_half_bin_3d_newtoff.cpp create mode 100644 src/nstencil_half_bin_3d_newtoff.h create mode 100644 src/nstencil_half_bin_3d_newton.cpp create mode 100644 src/nstencil_half_bin_3d_newton.h create mode 100644 src/nstencil_half_bin_3d_newton_ssa.cpp create mode 100644 src/nstencil_half_bin_3d_newton_ssa.h create mode 100644 src/nstencil_half_bin_3d_newton_tri.cpp create mode 100644 src/nstencil_half_bin_3d_newton_tri.h create mode 100644 src/nstencil_half_ghost_bin_2d_newtoff.cpp create mode 100644 src/nstencil_half_ghost_bin_2d_newtoff.h create mode 100644 src/nstencil_half_ghost_bin_3d_newtoff.cpp create mode 100644 src/nstencil_half_ghost_bin_3d_newtoff.h create mode 100644 src/nstencil_half_multi_2d_newtoff.cpp create mode 100644 src/nstencil_half_multi_2d_newtoff.h create mode 100644 src/nstencil_half_multi_2d_newton.cpp create mode 100644 src/nstencil_half_multi_2d_newton.h create mode 100644 src/nstencil_half_multi_2d_newton_tri.cpp create mode 100644 src/nstencil_half_multi_2d_newton_tri.h create mode 100644 src/nstencil_half_multi_3d_newtoff.cpp create mode 100644 src/nstencil_half_multi_3d_newtoff.h create mode 100644 src/nstencil_half_multi_3d_newton.cpp create mode 100644 src/nstencil_half_multi_3d_newton.h create mode 100644 src/nstencil_half_multi_3d_newton_tri.cpp create mode 100644 src/nstencil_half_multi_3d_newton_tri.h create mode 100644 src/ntopo.cpp create mode 100644 src/ntopo.h create mode 100644 src/ntopo_angle_all.cpp rename src/{neigh_full.h => ntopo_angle_all.h} (68%) create mode 100644 src/ntopo_angle_partial.cpp create mode 100644 src/ntopo_angle_partial.h create mode 100644 src/ntopo_angle_template.cpp create mode 100644 src/ntopo_angle_template.h create mode 100644 src/ntopo_bond_all.cpp rename src/{neigh_derive.h => ntopo_bond_all.h} (68%) create mode 100644 src/ntopo_bond_partial.cpp rename src/{neigh_half_bin.h => ntopo_bond_partial.h} (66%) create mode 100644 src/ntopo_bond_template.cpp create mode 100644 src/ntopo_bond_template.h create mode 100644 src/ntopo_dihedral_all.cpp create mode 100644 src/ntopo_dihedral_all.h create mode 100644 src/ntopo_dihedral_partial.cpp create mode 100644 src/ntopo_dihedral_partial.h create mode 100644 src/ntopo_dihedral_template.cpp create mode 100644 src/ntopo_dihedral_template.h create mode 100644 src/ntopo_improper_all.cpp create mode 100644 src/ntopo_improper_all.h create mode 100644 src/ntopo_improper_partial.cpp create mode 100644 src/ntopo_improper_partial.h create mode 100644 src/ntopo_improper_template.cpp create mode 100644 src/ntopo_improper_template.h diff --git a/src/Make.sh b/src/Make.sh index fbed1a8bcd..a76f7d5ac1 100644 --- a/src/Make.sh +++ b/src/Make.sh @@ -5,12 +5,6 @@ # sh Make.sh Makefile.shlib # sh Make.sh Makefile.list -# turn off enforced customizations -GREP_OPTIONS= -# enforce using portable C locale -LC_ALL=C -export LC_ALL GREP_OPTIONS - # function to create one style_*.h file # must whack *.d files that depend on style_*.h file, # else Make will not recreate them @@ -59,8 +53,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 +64,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 +72,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 37d137e838..b6398358de 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -13,6 +13,39 @@ 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 30 Aug 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 +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 31 May 2016 fix_ave_spatial_sphere.cpp fix_ave_spatial_sphere.h diff --git a/src/neigh_shardlow.cpp b/src/USER-DPD/#npair_half_bin_newton_ssa.cpp# similarity index 60% rename from src/neigh_shardlow.cpp rename to src/USER-DPD/#npair_half_bin_newton_ssa.cpp# index 1b87ab65d7..b529121a0a 100644 --- a/src/neigh_shardlow.cpp +++ b/src/USER-DPD/#npair_half_bin_newton_ssa.cpp# @@ -16,195 +16,38 @@ James Larentzos and Timothy I. Mattox (Engility Corporation) ------------------------------------------------------------------------- */ +#include "npair_half_bin_newton_ssa.h" #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 "my_page.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 -------------------------------------------------------------------------- */ +// allocate space for static class variable +// prototype for non-class function -/* ---------------------------------------------------------------------- */ - -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 *, const void *); -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; -} +/* ---------------------------------------------------------------------- */ +NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(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 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 + 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 Neighbor::half_bin_newton_ssa(NeighList *list) +void NPairHalfBinNewtonSSA::build(NeighList *list) { int i,j,k,n,itype,jtype,ibin,which,imol,iatom,moltemplate; tagint tagprev; @@ -220,6 +63,7 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) 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; @@ -232,18 +76,27 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) 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) -------------------------------------------------------------------------- */ + // bin owned and ghost atoms for use by Shardlow Splitting Algorithm + // exclude ghost atoms that are not in the Active Interaction Regions (AIR) + + // NOTE to Tim: this binatomflag no longer exists + // the logic up higher assures that binning has been done + // before this build() method is called + // maybe this code below needs to be in a new NBinShardlow class? + // this class also inherits NPair::nb from its parent + // which points to the NBin class that did the binning + // there are last_step variables stored there which indicate + // the last time binning was done + // the basic question is what data is created/stored by SSA binning + // and in what class should it live? + // if it is created by the binning operation, then I think + // it should be in a new NBinShardlow class + + if (true /* binatomflag */) { // only false in Neighbor::build_one if (mbins > list->maxhead_ssa) { list->maxhead_ssa = mbins; @@ -257,8 +110,8 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) list->binhead_ssa[i] = -1; } - if (maxbin > list->maxbin_ssa) { - list->maxbin_ssa = maxbin; + if (nall > list->maxbin_ssa) { + list->maxbin_ssa = nall; memory->destroy(list->bins_ssa); memory->create(list->bins_ssa,list->maxbin_ssa,"bins_ssa"); } @@ -267,7 +120,8 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) if (includegroup) { int bitmask = group->bitmask[includegroup]; - for (i = nall-1; i >= nlocal; i--) { + 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]); @@ -275,7 +129,6 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) 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 @@ -289,7 +142,7 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) list->bins_ssa[i] = list->binhead_ssa[ibin]; list->binhead_ssa[ibin] = i; } - } /* else reuse previous binning. See Neighbor::build_one comment. */ + } // else reuse previous binning. See Neighbor::build_one comment ipage->reset(); @@ -343,8 +196,10 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) 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]) { + 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; @@ -377,9 +232,10 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) // 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]) { + + if (ssaAIR[i] == 1) for (k = 0; k < nstencil_ssa; k++) { + 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; @@ -424,10 +280,12 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) 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. + // 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]; @@ -436,3 +294,18 @@ void Neighbor::half_bin_newton_ssa(NeighList *list) 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/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index fd9f4d7d74..f8fe426c77 100644 --- a/src/USER-DPD/fix_shardlow.cpp +++ b/src/USER-DPD/fix_shardlow.cpp @@ -226,7 +226,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; 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..b529121a0a --- /dev/null +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -0,0 +1,311 @@ +/* ---------------------------------------------------------------------- + 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 "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; + + int inum = 0; + + // bin owned and ghost atoms for use by Shardlow Splitting Algorithm + // exclude ghost atoms that are not in the Active Interaction Regions (AIR) + + // NOTE to Tim: this binatomflag no longer exists + // the logic up higher assures that binning has been done + // before this build() method is called + // maybe this code below needs to be in a new NBinShardlow class? + // this class also inherits NPair::nb from its parent + // which points to the NBin class that did the binning + // there are last_step variables stored there which indicate + // the last time binning was done + // the basic question is what data is created/stored by SSA binning + // and in what class should it live? + // if it is created by the binning operation, then I think + // it should be in a new NBinShardlow class + + if (true /* binatomflag */) { // only false in Neighbor::build_one + + 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 (nall > list->maxbin_ssa) { + list->maxbin_ssa = nall; + 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]; + 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]); + list->bins_ssa[i] = list->gbinhead_ssa[ibin]; + list->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]); + 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 < nstencil_ssa; k++) { + 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; +} + +/* ---------------------------------------------------------------------- + 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..a2e72d772b --- /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_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..8c53abfe80 --- /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) : + NStencil(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 = 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_ssa = 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..319a8ce670 --- /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.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin2dNewtonSSA : public NStencil { + 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..1ac15fe61e --- /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) : + NStencil(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 = 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_ssa = 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..8cb130a712 --- /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.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin3dNewtonSSA : public NStencil { + public: + NStencilHalfBin3dNewtonSSA(class LAMMPS *); + ~NStencilHalfBin3dNewtonSSA() {} + void create(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: + +*/ 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/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/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 dcf85f844e..0000000000 --- a/src/neigh_derive.cpp +++ /dev/null @@ -1,845 +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,*touchptr_skip; - double *shearptr,*shearptr_skip; - - 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,*touchptr_skip; - double *shearptr,*shearptr_skip; - - 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 itag,jtag; - int *surf,*neighptr,*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; - itag = tag[i]; - - 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; - itag = tag[i]; - - // 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..2a29c34565 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,117 @@ NeighList::NeighList(LAMMPS *lmp) : listcopy = NULL; listskip = NULL; + ipage = NULL; + dpage = 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; } /* ---------------------------------------------------------------------- */ 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) { + if (ssa) { + memory->sfree(ndxAIR_ssa); + memory->destroy(bins_ssa); memory->destroy(binhead_ssa); memory->destroy(gbinhead_ssa); } +} - 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; +/* ---------------------------------------------------------------------- + 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 (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 +185,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 +248,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 +268,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 +282,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 +302,17 @@ 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 (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatom; 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); - } - return bytes; } diff --git a/src/neigh_list.h b/src/neigh_list.h index d76682dfc4..232892f8b4 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 @@ -67,7 +71,6 @@ class NeighList : protected Pointers { // 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 @@ -75,30 +78,20 @@ class NeighList : protected Pointers { 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 post_constructor(class NeighRequest *); + void setup_pages(int, int); // setup page data structures + void grow(int,int); // grow all data structs void stencil_allocate(int, int); // allocate stencil arrays - void copy_skip_info(int *, int **); // copy skip info from a neigh request 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.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..e58fc7126e 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,346 @@ 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++) { + if (lmp->kokkos) nlist = init_lists_kokkos(); + else 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) { lists[i] = NULL; - pair_build[i] = NULL; - stencil_create[i] = NULL; + continue; } + lists[i] = new NeighList(lmp); + 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]); + } + } - // 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 + // morph requests via A,B,C rules + // this is to avoid duplicate or inefficient builds + // update both request and list when morph - for (i = 0; i < nrequest; i++) { - if (requests[i]->kokkos_host || requests[i]->kokkos_device) continue; - lists[i] = new NeighList(lmp); - lists[i]->index = i; + // (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 - 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]); + for (i = 0; i < nrequest; i++) { + if (!lists[i]) continue; + 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 (lists[i] == NULL) continue; // Kokkos + if (requests[i]->pair && requests[i]->half && requests[i]->newton != 2) { + for (j = 0; j < nrequest; j++) { + if (lists[j] == NULL) continue; // Kokkos + 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]; } } - - // 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 - - 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]; - } - } - } + } + + // (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 (lists[i] == NULL) continue; // Kokkos + if (!requests[i]->fix && !requests[i]->compute) continue; + for (j = 0; j < nrequest; j++) { + if (lists[j] == NULL) continue; // Kokkos + 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; } - - if (dnummax) { - delete [] zeroes; - zeroes = new double[dnummax]; - for (i = 0; i < dnummax; i++) zeroes[i] = 0.0; + for (j = 0; j < nrequest; j++) { + if (lists[j] == NULL) continue; // Kokkos + 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] == NULL) continue; // Kokkos + 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 (lists[i]) { + if (neigh_pair[i] && !lists[i]->copy) lists[i]->grow(maxatom,maxatom); + } else { + init_list_flags1_kokkos(i); + init_list_grow_kokkos(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"); + // 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]) { + if (lists[i]->occasional == 0 && lists[i]->pair_method) + plist[npair_perpetual++] = i; + } else init_list_flags2_kokkos(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->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"); + // 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++) { + if (!lists[plist[i]]) continue; // Kokkos check + 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->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"); - } + // debug output - // set flags that determine which topology neighboring routines to use +#ifdef NEIGH_LIST_DEBUG + for (i = 0; i < nrequest; i++) lists[i]->print_attributes(); +#endif +} + +/* ---------------------------------------------------------------------- + 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 +1002,488 @@ 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"; + else if (requests[i]->full_cluster) kind = "full/cluster"; // Kokkos + fprintf(out," kind: %s",kind); + + 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]->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 + + int ssaflag,intelflag; + + ssaflag = intelflag = 0; + + if (rq->ssa) ssaflag = NB_SSA; + if (rq->intel) intelflag = NB_INTEL; + + // 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; + + 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 + // 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; + + copyflag = skipflag = halfflag = fullflag = halffullflag = sizeflag = + ghostflag = respaflag = off2onflag = onesideflag = ssaflag = + ompflag = intelflag = 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; + + 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)) 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 (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 +1495,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 +1503,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 +1643,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 +1697,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 +1767,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 +1828,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 +1973,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 +1997,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 +2006,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..9655cca545 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,128 +101,123 @@ 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(); + void init_topology(); - // dummy functions provided by NeighborKokkos + void print_pairwise_info(); + void requests_new2old(); + + 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; virtual void init_cutneighsq_kokkos(int) {} virtual int init_lists_kokkos() {return 0;} @@ -200,164 +227,47 @@ class Neighbor : protected Pointers { 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 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; - }; }; +namespace NeighConst { + static const int NB_SSA = 1<<0; + static const int NB_INTEL = 1<<1; + + 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; +} + } #endif diff --git a/src/npair.cpp b/src/npair.cpp new file mode 100644 index 0000000000..20522cde48 --- /dev/null +++ b/src/npair.cpp @@ -0,0 +1,258 @@ +/* ---------------------------------------------------------------------- + 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; + nstencil_ssa = ns->nstencil_ssa; + 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..aba7256d73 --- /dev/null +++ b/src/npair.h @@ -0,0 +1,146 @@ +/* -*- 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() {} + 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 nstencil_ssa; + 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(); + void copy_bin_info(); + 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_gran.h b/src/npair_copy.h similarity index 67% rename from src/neigh_gran.h rename to src/npair_copy.h index 1538f7662a..62467c2d20 100644 --- a/src/neigh_gran.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_ssa.cpp b/src/npair_half_bin_newton_ssa.cpp new file mode 100644 index 0000000000..b529121a0a --- /dev/null +++ b/src/npair_half_bin_newton_ssa.cpp @@ -0,0 +1,311 @@ +/* ---------------------------------------------------------------------- + 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 "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; + + int inum = 0; + + // bin owned and ghost atoms for use by Shardlow Splitting Algorithm + // exclude ghost atoms that are not in the Active Interaction Regions (AIR) + + // NOTE to Tim: this binatomflag no longer exists + // the logic up higher assures that binning has been done + // before this build() method is called + // maybe this code below needs to be in a new NBinShardlow class? + // this class also inherits NPair::nb from its parent + // which points to the NBin class that did the binning + // there are last_step variables stored there which indicate + // the last time binning was done + // the basic question is what data is created/stored by SSA binning + // and in what class should it live? + // if it is created by the binning operation, then I think + // it should be in a new NBinShardlow class + + if (true /* binatomflag */) { // only false in Neighbor::build_one + + 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 (nall > list->maxbin_ssa) { + list->maxbin_ssa = nall; + 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]; + 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]); + list->bins_ssa[i] = list->gbinhead_ssa[ibin]; + list->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]); + 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 < nstencil_ssa; k++) { + 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; +} + +/* ---------------------------------------------------------------------- + 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/npair_half_bin_newton_ssa.h b/src/npair_half_bin_newton_ssa.h new file mode 100644 index 0000000000..a2e72d772b --- /dev/null +++ b/src/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_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/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_halffull_newton_ssa.cpp b/src/npair_halffull_newton_ssa.cpp new file mode 100644 index 0000000000..f09a2c3ae1 --- /dev/null +++ b/src/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/npair_halffull_newton_ssa.h b/src/npair_halffull_newton_ssa.h new file mode 100644 index 0000000000..4935349f77 --- /dev/null +++ b/src/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/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..5f403d7511 --- /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); + memory->destroy(nstencil_multi); + + 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 [] 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..c0ecfe2754 --- /dev/null +++ b/src/nstencil.h @@ -0,0 +1,84 @@ +/* -*- 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 nstencil_ssa; // # of total bins in SSA 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(); + 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_ssa.cpp b/src/nstencil_half_bin_2d_newton_ssa.cpp new file mode 100644 index 0000000000..8c53abfe80 --- /dev/null +++ b/src/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) : + NStencil(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 = 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_ssa = pos; // record where full stencil ends +} diff --git a/src/nstencil_half_bin_2d_newton_ssa.h b/src/nstencil_half_bin_2d_newton_ssa.h new file mode 100644 index 0000000000..319a8ce670 --- /dev/null +++ b/src/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.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin2dNewtonSSA : public NStencil { + public: + NStencilHalfBin2dNewtonSSA(class LAMMPS *); + ~NStencilHalfBin2dNewtonSSA() {} + 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_ssa.cpp b/src/nstencil_half_bin_3d_newton_ssa.cpp new file mode 100644 index 0000000000..1ac15fe61e --- /dev/null +++ b/src/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) : + NStencil(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 = 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_ssa = pos; // record where full stencil ends +} diff --git a/src/nstencil_half_bin_3d_newton_ssa.h b/src/nstencil_half_bin_3d_newton_ssa.h new file mode 100644 index 0000000000..8cb130a712 --- /dev/null +++ b/src/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.h" + +namespace LAMMPS_NS { + +class NStencilHalfBin3dNewtonSSA : public NStencil { + public: + NStencilHalfBin3dNewtonSSA(class LAMMPS *); + ~NStencilHalfBin3dNewtonSSA() {} + 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/neigh_half_bin.h b/src/ntopo_bond_partial.h similarity index 66% rename from src/neigh_half_bin.h rename to src/ntopo_bond_partial.h index 1538f7662a..b0a2c274b2 100644 --- a/src/neigh_half_bin.h +++ b/src/ntopo_bond_partial.h @@ -11,12 +11,31 @@ 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: -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_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: + +*/ From 9b7a0d7e1c1ad4636dddc84aac70ec6e71cdddbb Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 5 Sep 2016 14:43:57 -0400 Subject: [PATCH 02/22] Update gitignore for the new USER-DPD source files. --- src/.gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/.gitignore b/src/.gitignore index 6e8f637d95..32947776b6 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 From 8ed3f4226e5b5e11b9ccde7fb6e8a5e5725f913a Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 5 Sep 2016 15:05:23 -0400 Subject: [PATCH 03/22] USER-DPD: move custom binning stuff to a NBinSSA child class. Removes most SSA specific fields from class NeighList. --- src/USER-DPD/nbin_ssa.cpp | 129 +++++++++++++++++++++ src/USER-DPD/nbin_ssa.h | 54 +++++++++ src/USER-DPD/npair_half_bin_newton_ssa.cpp | 81 ++----------- src/neigh_list.cpp | 13 --- src/neigh_list.h | 5 - 5 files changed, 195 insertions(+), 87 deletions(-) create mode 100644 src/USER-DPD/nbin_ssa.cpp create mode 100644 src/USER-DPD/nbin_ssa.h 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 index b529121a0a..e41b9d4276 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -18,6 +18,7 @@ #include "npair_half_bin_newton_ssa.h" #include "neighbor.h" +#include "nbin_ssa.h" #include "neigh_list.h" #include "atom.h" #include "atom_vec.h" @@ -78,72 +79,14 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) int **firstneigh = list->firstneigh; MyPage *ipage = list->ipage; + 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; - // bin owned and ghost atoms for use by Shardlow Splitting Algorithm - // exclude ghost atoms that are not in the Active Interaction Regions (AIR) - - // NOTE to Tim: this binatomflag no longer exists - // the logic up higher assures that binning has been done - // before this build() method is called - // maybe this code below needs to be in a new NBinShardlow class? - // this class also inherits NPair::nb from its parent - // which points to the NBin class that did the binning - // there are last_step variables stored there which indicate - // the last time binning was done - // the basic question is what data is created/stored by SSA binning - // and in what class should it live? - // if it is created by the binning operation, then I think - // it should be in a new NBinShardlow class - - if (true /* binatomflag */) { // only false in Neighbor::build_one - - 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 (nall > list->maxbin_ssa) { - list->maxbin_ssa = nall; - 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]; - 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]); - list->bins_ssa[i] = list->gbinhead_ssa[ibin]; - list->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]); - 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 @@ -166,7 +109,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // 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]) { + for (j = bins_ssa[i]; j >= 0; j = bins_ssa[j]) { jtype = type[j]; if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; @@ -198,8 +141,8 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // 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]) { + 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; @@ -234,8 +177,8 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // Note2: only non-pure locals can have ghosts as neighbors if (ssaAIR[i] == 1) for (k = 0; k < nstencil_ssa; k++) { - for (j = list->gbinhead_ssa[ibin+stencil[k]]; j >= 0; - j = list->bins_ssa[j]) { + 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; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index 2a29c34565..dfab9b023a 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -70,11 +70,6 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) // USER-DPD package ndxAIR_ssa = NULL; - maxbin_ssa = 0; - bins_ssa = NULL; - maxhead_ssa = 0; - binhead_ssa = NULL; - gbinhead_ssa = NULL; } /* ---------------------------------------------------------------------- */ @@ -96,9 +91,6 @@ NeighList::~NeighList() if (ssa) { memory->sfree(ndxAIR_ssa); - memory->destroy(bins_ssa); - memory->destroy(binhead_ssa); - memory->destroy(gbinhead_ssa); } } @@ -308,11 +300,6 @@ bigint NeighList::memory_usage() } if (ndxAIR_ssa) bytes += sizeof(uint16_t) * 8 * maxatom; - 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/neigh_list.h b/src/neigh_list.h index 232892f8b4..d3bde212c2 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -72,11 +72,6 @@ class NeighList : protected Pointers { // USER-DPD package and Shardlow Splitting Algorithm (SSA) support 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 // methods From 82c6eb467539d7907784352b6478a65737ba7931 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Mon, 5 Sep 2016 16:06:43 -0400 Subject: [PATCH 04/22] USER-DPD: Set missing NP_HALF flag in npair_half_bin_newton_ssa.h --- src/USER-DPD/npair_half_bin_newton_ssa.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.h b/src/USER-DPD/npair_half_bin_newton_ssa.h index a2e72d772b..13347b33b0 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.h +++ b/src/USER-DPD/npair_half_bin_newton_ssa.h @@ -15,7 +15,7 @@ NPairStyle(half/bin/newton/ssa, NPairHalfBinNewtonSSA, - NP_BIN | NP_NEWTON | NP_ORTHO | NP_SSA) + NP_HALF | NP_BIN | NP_NEWTON | NP_ORTHO | NP_SSA) #else From 81fcbcd99cd05b3cf23541de628d5a8f0475839c Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Wed, 7 Sep 2016 16:06:38 -0400 Subject: [PATCH 05/22] USER-DPD: move nstencil_ssa out of core LAMMPS into USER-DPD --- src/USER-DPD/npair_half_bin_newton_ssa.cpp | 10 ++++-- .../nstencil_half_bin_2d_newton_ssa.cpp | 6 ++-- .../nstencil_half_bin_2d_newton_ssa.h | 4 +-- .../nstencil_half_bin_3d_newton_ssa.cpp | 6 ++-- .../nstencil_half_bin_3d_newton_ssa.h | 4 +-- src/USER-DPD/nstencil_ssa.h | 36 +++++++++++++++++++ src/npair.cpp | 1 - src/npair.h | 1 - src/nstencil.h | 1 - 9 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 src/USER-DPD/nstencil_ssa.h diff --git a/src/USER-DPD/npair_half_bin_newton_ssa.cpp b/src/USER-DPD/npair_half_bin_newton_ssa.cpp index e41b9d4276..fa000233a9 100644 --- a/src/USER-DPD/npair_half_bin_newton_ssa.cpp +++ b/src/USER-DPD/npair_half_bin_newton_ssa.cpp @@ -18,6 +18,7 @@ #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" @@ -79,6 +80,11 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) 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; @@ -140,7 +146,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // loop over all local atoms in other bins in "half" stencil - for (k = 0; k < nstencil; k++) { + for (k = 0; k < nstencil_half; k++) { for (j = binhead_ssa[ibin+stencil[k]]; j >= 0; j = bins_ssa[j]) { @@ -176,7 +182,7 @@ void NPairHalfBinNewtonSSA::build(NeighList *list) // 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_ssa; k++) { + if (ssaAIR[i] == 1) for (k = 0; k < nstencil_full; k++) { for (j = gbinhead_ssa[ibin+stencil[k]]; j >= 0; j = bins_ssa[j]) { diff --git a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp index 8c53abfe80..4c548c783c 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.cpp @@ -25,7 +25,7 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ NStencilHalfBin2dNewtonSSA::NStencilHalfBin2dNewtonSSA(LAMMPS *lmp) : - NStencil(lmp) {} + NStencilSSA(lmp) {} /* ---------------------------------------------------------------------- create stencil based on bin geometry and cutoff @@ -49,7 +49,7 @@ void NStencilHalfBin2dNewtonSSA::create() if (bin_distance(i,j,0) < cutneighmaxsq) stencil[pos++] = j*mbinx + i; - nstencil = pos; // record where normal half stencil ends + nstencil_half = pos; // record where normal half stencil ends // include additional bins for AIR ghosts only @@ -60,5 +60,5 @@ void NStencilHalfBin2dNewtonSSA::create() stencil[pos++] = j*mbinx + i; } - nstencil_ssa = pos; // record where full stencil ends + 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 index 319a8ce670..30901bb3e2 100644 --- a/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h +++ b/src/USER-DPD/nstencil_half_bin_2d_newton_ssa.h @@ -22,11 +22,11 @@ NStencilStyle(half/bin/2d/newton/ssa, #ifndef LMP_NSTENCIL_HALF_BIN_2D_NEWTON_SSA_H #define LMP_NSTENCIL_HALF_BIN_2D_NEWTON_SSA_H -#include "nstencil.h" +#include "nstencil_ssa.h" namespace LAMMPS_NS { -class NStencilHalfBin2dNewtonSSA : public NStencil { +class NStencilHalfBin2dNewtonSSA : public NStencilSSA { public: NStencilHalfBin2dNewtonSSA(class LAMMPS *); ~NStencilHalfBin2dNewtonSSA() {} diff --git a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp index 1ac15fe61e..4b8bd27016 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.cpp @@ -25,7 +25,7 @@ using namespace LAMMPS_NS; /* ---------------------------------------------------------------------- */ NStencilHalfBin3dNewtonSSA::NStencilHalfBin3dNewtonSSA(LAMMPS *lmp) : - NStencil(lmp) {} + NStencilSSA(lmp) {} /* ---------------------------------------------------------------------- create stencil based on bin geometry and cutoff @@ -50,7 +50,7 @@ void NStencilHalfBin3dNewtonSSA::create() if (bin_distance(i,j,k) < cutneighmaxsq) stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; - nstencil = pos; // record where normal half stencil ends + nstencil_half = pos; // record where normal half stencil ends // include additional bins for AIR ghosts only @@ -70,5 +70,5 @@ void NStencilHalfBin3dNewtonSSA::create() stencil[pos++] = k*mbiny*mbinx + j*mbinx + i; } - nstencil_ssa = pos; // record where full stencil ends + 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 index 8cb130a712..7765b256d3 100644 --- a/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h +++ b/src/USER-DPD/nstencil_half_bin_3d_newton_ssa.h @@ -22,11 +22,11 @@ NStencilStyle(half/bin/3d/newton/ssa, #ifndef LMP_NSTENCIL_HALF_BIN_3D_NEWTON_SSA_H #define LMP_NSTENCIL_HALF_BIN_3D_NEWTON_SSA_H -#include "nstencil.h" +#include "nstencil_ssa.h" namespace LAMMPS_NS { -class NStencilHalfBin3dNewtonSSA : public NStencil { +class NStencilHalfBin3dNewtonSSA : public NStencilSSA { public: NStencilHalfBin3dNewtonSSA(class LAMMPS *); ~NStencilHalfBin3dNewtonSSA() {} diff --git a/src/USER-DPD/nstencil_ssa.h b/src/USER-DPD/nstencil_ssa.h new file mode 100644 index 0000000000..9fcd19ee26 --- /dev/null +++ b/src/USER-DPD/nstencil_ssa.h @@ -0,0 +1,36 @@ +/* -*- 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_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: + +*/ diff --git a/src/npair.cpp b/src/npair.cpp index 20522cde48..6ea4e62550 100644 --- a/src/npair.cpp +++ b/src/npair.cpp @@ -113,7 +113,6 @@ void NPair::copy_bin_info() void NPair::copy_stencil_info() { nstencil = ns->nstencil; - nstencil_ssa = ns->nstencil_ssa; stencil = ns->stencil; stencilxyz = ns->stencilxyz; nstencil_multi = ns->nstencil_multi; diff --git a/src/npair.h b/src/npair.h index aba7256d73..70fcc5c452 100644 --- a/src/npair.h +++ b/src/npair.h @@ -81,7 +81,6 @@ class NPair : protected Pointers { // data from NStencil class int nstencil; - int nstencil_ssa; int *stencil; int **stencilxyz; int *nstencil_multi; diff --git a/src/nstencil.h b/src/nstencil.h index c0ecfe2754..b9c6dd58fb 100644 --- a/src/nstencil.h +++ b/src/nstencil.h @@ -28,7 +28,6 @@ class NStencil : protected Pointers { bigint last_copy_bin; int nstencil; // # of bins in stencil - int nstencil_ssa; // # of total bins in SSA stencil int *stencil; // list of bin offsets int **stencilxyz; // bin offsets in xyz dims int *nstencil_multi; // # bins in each type-based multi stencil From 2f02d984697630a4f1833a23d13383fef472a571 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 9 Sep 2016 13:53:07 -0400 Subject: [PATCH 06/22] remove USER-DPD files that should not be where they are --- src/USER-DPD/#npair_half_bin_newton_ssa.cpp# | 311 ------------------- src/npair_half_bin_newton_ssa.cpp | 311 ------------------- src/npair_half_bin_newton_ssa.h | 43 --- src/nstencil_half_bin_2d_newton_ssa.cpp | 64 ---- src/nstencil_half_bin_2d_newton_ssa.h | 43 --- src/nstencil_half_bin_3d_newton_ssa.cpp | 74 ----- src/nstencil_half_bin_3d_newton_ssa.h | 43 --- 7 files changed, 889 deletions(-) delete mode 100644 src/USER-DPD/#npair_half_bin_newton_ssa.cpp# delete mode 100644 src/npair_half_bin_newton_ssa.cpp delete mode 100644 src/npair_half_bin_newton_ssa.h delete mode 100644 src/nstencil_half_bin_2d_newton_ssa.cpp delete mode 100644 src/nstencil_half_bin_2d_newton_ssa.h delete mode 100644 src/nstencil_half_bin_3d_newton_ssa.cpp delete mode 100644 src/nstencil_half_bin_3d_newton_ssa.h diff --git a/src/USER-DPD/#npair_half_bin_newton_ssa.cpp# b/src/USER-DPD/#npair_half_bin_newton_ssa.cpp# deleted file mode 100644 index b529121a0a..0000000000 --- a/src/USER-DPD/#npair_half_bin_newton_ssa.cpp# +++ /dev/null @@ -1,311 +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 "npair_half_bin_newton_ssa.h" -#include "neighbor.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; - - int inum = 0; - - // bin owned and ghost atoms for use by Shardlow Splitting Algorithm - // exclude ghost atoms that are not in the Active Interaction Regions (AIR) - - // NOTE to Tim: this binatomflag no longer exists - // the logic up higher assures that binning has been done - // before this build() method is called - // maybe this code below needs to be in a new NBinShardlow class? - // this class also inherits NPair::nb from its parent - // which points to the NBin class that did the binning - // there are last_step variables stored there which indicate - // the last time binning was done - // the basic question is what data is created/stored by SSA binning - // and in what class should it live? - // if it is created by the binning operation, then I think - // it should be in a new NBinShardlow class - - if (true /* binatomflag */) { // only false in Neighbor::build_one - - 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 (nall > list->maxbin_ssa) { - list->maxbin_ssa = nall; - 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]; - 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]); - list->bins_ssa[i] = list->gbinhead_ssa[ibin]; - list->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]); - 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 < nstencil_ssa; k++) { - 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; -} - -/* ---------------------------------------------------------------------- - 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/npair_half_bin_newton_ssa.cpp b/src/npair_half_bin_newton_ssa.cpp deleted file mode 100644 index b529121a0a..0000000000 --- a/src/npair_half_bin_newton_ssa.cpp +++ /dev/null @@ -1,311 +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 "npair_half_bin_newton_ssa.h" -#include "neighbor.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; - - int inum = 0; - - // bin owned and ghost atoms for use by Shardlow Splitting Algorithm - // exclude ghost atoms that are not in the Active Interaction Regions (AIR) - - // NOTE to Tim: this binatomflag no longer exists - // the logic up higher assures that binning has been done - // before this build() method is called - // maybe this code below needs to be in a new NBinShardlow class? - // this class also inherits NPair::nb from its parent - // which points to the NBin class that did the binning - // there are last_step variables stored there which indicate - // the last time binning was done - // the basic question is what data is created/stored by SSA binning - // and in what class should it live? - // if it is created by the binning operation, then I think - // it should be in a new NBinShardlow class - - if (true /* binatomflag */) { // only false in Neighbor::build_one - - 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 (nall > list->maxbin_ssa) { - list->maxbin_ssa = nall; - 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]; - 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]); - list->bins_ssa[i] = list->gbinhead_ssa[ibin]; - list->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]); - 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 < nstencil_ssa; k++) { - 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; -} - -/* ---------------------------------------------------------------------- - 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/npair_half_bin_newton_ssa.h b/src/npair_half_bin_newton_ssa.h deleted file mode 100644 index a2e72d772b..0000000000 --- a/src/npair_half_bin_newton_ssa.h +++ /dev/null @@ -1,43 +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. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS - -NPairStyle(half/bin/newton/ssa, - NPairHalfBinNewtonSSA, - 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/nstencil_half_bin_2d_newton_ssa.cpp b/src/nstencil_half_bin_2d_newton_ssa.cpp deleted file mode 100644 index 8c53abfe80..0000000000 --- a/src/nstencil_half_bin_2d_newton_ssa.cpp +++ /dev/null @@ -1,64 +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 "nstencil_half_bin_2d_newton_ssa.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfBin2dNewtonSSA::NStencilHalfBin2dNewtonSSA(LAMMPS *lmp) : - NStencil(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 = 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_ssa = pos; // record where full stencil ends -} diff --git a/src/nstencil_half_bin_2d_newton_ssa.h b/src/nstencil_half_bin_2d_newton_ssa.h deleted file mode 100644 index 319a8ce670..0000000000 --- a/src/nstencil_half_bin_2d_newton_ssa.h +++ /dev/null @@ -1,43 +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. -------------------------------------------------------------------------- */ - -#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.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin2dNewtonSSA : public NStencil { - public: - NStencilHalfBin2dNewtonSSA(class LAMMPS *); - ~NStencilHalfBin2dNewtonSSA() {} - void create(); -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -*/ diff --git a/src/nstencil_half_bin_3d_newton_ssa.cpp b/src/nstencil_half_bin_3d_newton_ssa.cpp deleted file mode 100644 index 1ac15fe61e..0000000000 --- a/src/nstencil_half_bin_3d_newton_ssa.cpp +++ /dev/null @@ -1,74 +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 "nstencil_half_bin_3d_newton_ssa.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfBin3dNewtonSSA::NStencilHalfBin3dNewtonSSA(LAMMPS *lmp) : - NStencil(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 = 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_ssa = pos; // record where full stencil ends -} diff --git a/src/nstencil_half_bin_3d_newton_ssa.h b/src/nstencil_half_bin_3d_newton_ssa.h deleted file mode 100644 index 8cb130a712..0000000000 --- a/src/nstencil_half_bin_3d_newton_ssa.h +++ /dev/null @@ -1,43 +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. -------------------------------------------------------------------------- */ - -#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.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin3dNewtonSSA : public NStencil { - public: - NStencilHalfBin3dNewtonSSA(class LAMMPS *); - ~NStencilHalfBin3dNewtonSSA() {} - void create(); -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -*/ From 40f85c93ba4e634cb9f3359046eb29019c37622b Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 9 Sep 2016 14:10:42 -0400 Subject: [PATCH 07/22] corrected mismatched free() vs. delete[] --- src/nstencil.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nstencil.cpp b/src/nstencil.cpp index 5f403d7511..68d5f80412 100644 --- a/src/nstencil.cpp +++ b/src/nstencil.cpp @@ -77,7 +77,6 @@ NStencil::~NStencil() { memory->destroy(stencil); memory->destroy(stencilxyz); - memory->destroy(nstencil_multi); if (!stencil_multi) return; @@ -86,6 +85,7 @@ NStencil::~NStencil() memory->destroy(stencil_multi[i]); memory->destroy(distsq_multi[i]); } + delete [] nstencil_multi; delete [] stencil_multi; delete [] distsq_multi; } From 212c2617f6e4559ebe526174e64fa52d6a331914 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 9 Sep 2016 14:56:23 -0400 Subject: [PATCH 08/22] delete a couple more files, that don't belong into src/ --- src/npair_halffull_newton_ssa.cpp | 132 ------------------------------ src/npair_halffull_newton_ssa.h | 44 ---------- 2 files changed, 176 deletions(-) delete mode 100644 src/npair_halffull_newton_ssa.cpp delete mode 100644 src/npair_halffull_newton_ssa.h diff --git a/src/npair_halffull_newton_ssa.cpp b/src/npair_halffull_newton_ssa.cpp deleted file mode 100644 index f09a2c3ae1..0000000000 --- a/src/npair_halffull_newton_ssa.cpp +++ /dev/null @@ -1,132 +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 "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/npair_halffull_newton_ssa.h b/src/npair_halffull_newton_ssa.h deleted file mode 100644 index 4935349f77..0000000000 --- a/src/npair_halffull_newton_ssa.h +++ /dev/null @@ -1,44 +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. -------------------------------------------------------------------------- */ - -#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: - -*/ From 32c240978aa33213d355a1fceac8d644c666217e Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 9 Sep 2016 15:17:42 -0400 Subject: [PATCH 09/22] USER-DPD: remove several files from src that came from src/USER-DPD/ These were accidentally added to git in c9c2ae6. --- src/npair_half_bin_newton_ssa.cpp | 311 ------------------------ src/npair_half_bin_newton_ssa.h | 43 ---- src/npair_halffull_newton_ssa.cpp | 132 ---------- src/npair_halffull_newton_ssa.h | 44 ---- src/nstencil_half_bin_2d_newton_ssa.cpp | 64 ----- src/nstencil_half_bin_2d_newton_ssa.h | 43 ---- src/nstencil_half_bin_3d_newton_ssa.cpp | 74 ------ src/nstencil_half_bin_3d_newton_ssa.h | 43 ---- 8 files changed, 754 deletions(-) delete mode 100644 src/npair_half_bin_newton_ssa.cpp delete mode 100644 src/npair_half_bin_newton_ssa.h delete mode 100644 src/npair_halffull_newton_ssa.cpp delete mode 100644 src/npair_halffull_newton_ssa.h delete mode 100644 src/nstencil_half_bin_2d_newton_ssa.cpp delete mode 100644 src/nstencil_half_bin_2d_newton_ssa.h delete mode 100644 src/nstencil_half_bin_3d_newton_ssa.cpp delete mode 100644 src/nstencil_half_bin_3d_newton_ssa.h diff --git a/src/npair_half_bin_newton_ssa.cpp b/src/npair_half_bin_newton_ssa.cpp deleted file mode 100644 index b529121a0a..0000000000 --- a/src/npair_half_bin_newton_ssa.cpp +++ /dev/null @@ -1,311 +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 "npair_half_bin_newton_ssa.h" -#include "neighbor.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; - - int inum = 0; - - // bin owned and ghost atoms for use by Shardlow Splitting Algorithm - // exclude ghost atoms that are not in the Active Interaction Regions (AIR) - - // NOTE to Tim: this binatomflag no longer exists - // the logic up higher assures that binning has been done - // before this build() method is called - // maybe this code below needs to be in a new NBinShardlow class? - // this class also inherits NPair::nb from its parent - // which points to the NBin class that did the binning - // there are last_step variables stored there which indicate - // the last time binning was done - // the basic question is what data is created/stored by SSA binning - // and in what class should it live? - // if it is created by the binning operation, then I think - // it should be in a new NBinShardlow class - - if (true /* binatomflag */) { // only false in Neighbor::build_one - - 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 (nall > list->maxbin_ssa) { - list->maxbin_ssa = nall; - 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]; - 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]); - list->bins_ssa[i] = list->gbinhead_ssa[ibin]; - list->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]); - 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 < nstencil_ssa; k++) { - 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; -} - -/* ---------------------------------------------------------------------- - 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/npair_half_bin_newton_ssa.h b/src/npair_half_bin_newton_ssa.h deleted file mode 100644 index a2e72d772b..0000000000 --- a/src/npair_half_bin_newton_ssa.h +++ /dev/null @@ -1,43 +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. -------------------------------------------------------------------------- */ - -#ifdef NPAIR_CLASS - -NPairStyle(half/bin/newton/ssa, - NPairHalfBinNewtonSSA, - 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/npair_halffull_newton_ssa.cpp b/src/npair_halffull_newton_ssa.cpp deleted file mode 100644 index f09a2c3ae1..0000000000 --- a/src/npair_halffull_newton_ssa.cpp +++ /dev/null @@ -1,132 +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 "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/npair_halffull_newton_ssa.h b/src/npair_halffull_newton_ssa.h deleted file mode 100644 index 4935349f77..0000000000 --- a/src/npair_halffull_newton_ssa.h +++ /dev/null @@ -1,44 +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. -------------------------------------------------------------------------- */ - -#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/nstencil_half_bin_2d_newton_ssa.cpp b/src/nstencil_half_bin_2d_newton_ssa.cpp deleted file mode 100644 index 8c53abfe80..0000000000 --- a/src/nstencil_half_bin_2d_newton_ssa.cpp +++ /dev/null @@ -1,64 +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 "nstencil_half_bin_2d_newton_ssa.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfBin2dNewtonSSA::NStencilHalfBin2dNewtonSSA(LAMMPS *lmp) : - NStencil(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 = 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_ssa = pos; // record where full stencil ends -} diff --git a/src/nstencil_half_bin_2d_newton_ssa.h b/src/nstencil_half_bin_2d_newton_ssa.h deleted file mode 100644 index 319a8ce670..0000000000 --- a/src/nstencil_half_bin_2d_newton_ssa.h +++ /dev/null @@ -1,43 +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. -------------------------------------------------------------------------- */ - -#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.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin2dNewtonSSA : public NStencil { - public: - NStencilHalfBin2dNewtonSSA(class LAMMPS *); - ~NStencilHalfBin2dNewtonSSA() {} - void create(); -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -*/ diff --git a/src/nstencil_half_bin_3d_newton_ssa.cpp b/src/nstencil_half_bin_3d_newton_ssa.cpp deleted file mode 100644 index 1ac15fe61e..0000000000 --- a/src/nstencil_half_bin_3d_newton_ssa.cpp +++ /dev/null @@ -1,74 +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 "nstencil_half_bin_3d_newton_ssa.h" -#include "neighbor.h" -#include "neigh_list.h" - -using namespace LAMMPS_NS; - -/* ---------------------------------------------------------------------- */ - -NStencilHalfBin3dNewtonSSA::NStencilHalfBin3dNewtonSSA(LAMMPS *lmp) : - NStencil(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 = 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_ssa = pos; // record where full stencil ends -} diff --git a/src/nstencil_half_bin_3d_newton_ssa.h b/src/nstencil_half_bin_3d_newton_ssa.h deleted file mode 100644 index 8cb130a712..0000000000 --- a/src/nstencil_half_bin_3d_newton_ssa.h +++ /dev/null @@ -1,43 +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. -------------------------------------------------------------------------- */ - -#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.h" - -namespace LAMMPS_NS { - -class NStencilHalfBin3dNewtonSSA : public NStencil { - public: - NStencilHalfBin3dNewtonSSA(class LAMMPS *); - ~NStencilHalfBin3dNewtonSSA() {} - void create(); -}; - -} - -#endif -#endif - -/* ERROR/WARNING messages: - -*/ From 3842aa609531430dfed1d4638609354283558e33 Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 9 Sep 2016 15:23:40 -0400 Subject: [PATCH 10/22] forward skip lists /omp neighbor list builds to non-omp implementations --- src/USER-OMP/npair_skip_omp.h | 51 +++++++++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 src/USER-OMP/npair_skip_omp.h 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: + +*/ From 232abf853468a1a3e6fd86cabc20fea38af737ce Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Fri, 9 Sep 2016 15:42:14 -0400 Subject: [PATCH 11/22] restore locale and enforce grep option squashing --- src/Make.sh | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/Make.sh b/src/Make.sh index a76f7d5ac1..83880780ec 100644 --- a/src/Make.sh +++ b/src/Make.sh @@ -5,6 +5,12 @@ # sh Make.sh Makefile.shlib # sh Make.sh Makefile.list +# turn off enforced customizations +GREP_OPTIONS= +# enforce using portable C locale +LC_ALL=C +export LC_ALL GREP_OPTIONS + # function to create one style_*.h file # must whack *.d files that depend on style_*.h file, # else Make will not recreate them From 8318c6781697cdb8dd88a3208758c367295a99d2 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Wed, 7 Dec 2016 13:00:27 -0700 Subject: [PATCH 12/22] Kokkos neighbor refactor --- src/KOKKOS/Install.sh | 7 +- src/KOKKOS/atom_vec_kokkos.h | 14 +- src/KOKKOS/fix_qeq_reax_kokkos.cpp | 2 - src/KOKKOS/kokkos.cpp | 49 +- src/KOKKOS/kokkos.h | 1 - src/KOKKOS/nbin_kokkos.cpp | 144 ++++ src/KOKKOS/nbin_kokkos.h | 153 ++++ src/KOKKOS/neigh_list_kokkos.cpp | 48 +- src/KOKKOS/neigh_list_kokkos.h | 15 +- src/KOKKOS/neighbor_kokkos.cpp | 374 ++------- src/KOKKOS/neighbor_kokkos.h | 368 +-------- src/KOKKOS/npair_kokkos.cpp | 746 ++++++++++++++++++ src/KOKKOS/npair_kokkos.h | 435 ++++++++++ src/KOKKOS/pair_buck_coul_cut_kokkos.cpp | 9 +- src/KOKKOS/pair_buck_coul_long_kokkos.cpp | 4 +- src/KOKKOS/pair_buck_kokkos.cpp | 9 +- src/KOKKOS/pair_buck_kokkos.h | 5 +- src/KOKKOS/pair_coul_cut_kokkos.cpp | 4 +- src/KOKKOS/pair_coul_debye_kokkos.cpp | 9 +- src/KOKKOS/pair_coul_dsf_kokkos.cpp | 2 - src/KOKKOS/pair_coul_long_kokkos.cpp | 4 +- src/KOKKOS/pair_coul_wolf_kokkos.cpp | 2 - src/KOKKOS/pair_eam_alloy_kokkos.cpp | 2 - src/KOKKOS/pair_eam_fs_kokkos.cpp | 2 - src/KOKKOS/pair_eam_kokkos.cpp | 2 - src/KOKKOS/pair_kokkos.h | 189 +---- ..._lj_charmm_coul_charmm_implicit_kokkos.cpp | 4 +- .../pair_lj_charmm_coul_charmm_kokkos.cpp | 4 +- .../pair_lj_charmm_coul_long_kokkos.cpp | 4 +- src/KOKKOS/pair_lj_class2_coul_cut_kokkos.cpp | 9 +- .../pair_lj_class2_coul_long_kokkos.cpp | 4 +- src/KOKKOS/pair_lj_class2_kokkos.cpp | 9 +- src/KOKKOS/pair_lj_class2_kokkos.h | 5 +- src/KOKKOS/pair_lj_cut_coul_cut_kokkos.cpp | 9 +- src/KOKKOS/pair_lj_cut_coul_debye_kokkos.cpp | 9 +- src/KOKKOS/pair_lj_cut_coul_dsf_kokkos.cpp | 9 +- src/KOKKOS/pair_lj_cut_coul_long_kokkos.cpp | 4 +- src/KOKKOS/pair_lj_cut_kokkos.cpp | 9 +- src/KOKKOS/pair_lj_cut_kokkos.h | 5 +- src/KOKKOS/pair_lj_expand_kokkos.cpp | 9 +- src/KOKKOS/pair_lj_expand_kokkos.h | 5 +- .../pair_lj_gromacs_coul_gromacs_kokkos.cpp | 4 +- src/KOKKOS/pair_lj_gromacs_kokkos.cpp | 4 +- src/KOKKOS/pair_lj_sdk_kokkos.cpp | 9 +- src/KOKKOS/pair_lj_sdk_kokkos.h | 5 +- src/KOKKOS/pair_reax_c_kokkos.cpp | 2 - src/KOKKOS/pair_sw_kokkos.cpp | 1 - src/KOKKOS/pair_table_kokkos.cpp | 35 +- src/KOKKOS/pair_table_kokkos.h | 10 +- src/KOKKOS/pair_tersoff_kokkos.cpp | 41 +- src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 43 +- src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 49 +- src/KOKKOS/region_block_kokkos.h | 2 +- src/finish.cpp | 27 +- src/neigh_list.cpp | 5 + src/neigh_list.h | 6 +- src/neighbor.cpp | 62 +- src/neighbor.h | 11 +- src/npair.h | 6 +- src/nstencil.h | 2 +- 60 files changed, 1742 insertions(+), 1279 deletions(-) create mode 100644 src/KOKKOS/nbin_kokkos.cpp create mode 100644 src/KOKKOS/nbin_kokkos.h create mode 100644 src/KOKKOS/npair_kokkos.cpp create mode 100644 src/KOKKOS/npair_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 93adf58ef5..ebafb87466 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -105,11 +105,14 @@ 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_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 @@ -169,8 +172,6 @@ action pair_reax_c_kokkos.cpp pair_reax_c.cpp action pair_reax_c_kokkos.h pair_reax_c.h action pair_sw_kokkos.cpp pair_sw.cpp action pair_sw_kokkos.h pair_sw.h -action pair_vashishta_kokkos.cpp pair_vashishta.cpp -action pair_vashishta_kokkos.h pair_vashishta.h action pair_table_kokkos.cpp action pair_table_kokkos.h action pair_tersoff_kokkos.cpp pair_tersoff.cpp diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index 7ac66f1626..fbeeaf96be 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -83,13 +83,8 @@ class AtomVecKokkos : public AtomVec { std::is_same::value, Kokkos::CudaHostPinnedSpace,typename ViewType::memory_space>::type, Kokkos::MemoryTraits > mirror_type; - if (buffer_size == 0) { - buffer = Kokkos::kokkos_malloc(src.capacity()); - buffer_size = src.capacity(); - } else if (buffer_size < src.capacity()) { + if(buffer_size < src.capacity()) buffer = Kokkos::kokkos_realloc(buffer,src.capacity()); - buffer_size = src.capacity(); - } return mirror_type( buffer , src.dimension_0() , src.dimension_1() , @@ -109,13 +104,8 @@ class AtomVecKokkos : public AtomVec { std::is_same::value, Kokkos::CudaHostPinnedSpace,typename ViewType::memory_space>::type, Kokkos::MemoryTraits > mirror_type; - if (buffer_size == 0) { - buffer = Kokkos::kokkos_malloc(src.capacity()*sizeof(typename ViewType::value_type)); - buffer_size = src.capacity(); - } else if (buffer_size < src.capacity()) { + if(buffer_size < src.capacity()) buffer = Kokkos::kokkos_realloc(buffer,src.capacity()*sizeof(typename ViewType::value_type)); - buffer_size = src.capacity(); - } mirror_type tmp_view( (typename ViewType::value_type*)buffer , src.dimension_0() , src.dimension_1() , 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..feec72f45a --- /dev/null +++ b/src/KOKKOS/nbin_kokkos.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 "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; + } + } +} + +/* ---------------------------------------------------------------------- */ + +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..393fa478a1 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; + 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..ff154c9919 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -21,11 +21,10 @@ #include "atom_masks.h" #include "error.h" #include "kokkos.h" -#include "force.h" -#include "bond.h" -#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 +35,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 +50,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 +73,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 +90,13 @@ void NeighborKokkos::init_cutneighsq_kokkos(int n) /* ---------------------------------------------------------------------- */ -int NeighborKokkos::init_lists_kokkos() +void NeighborKokkos::create_kokkos_list(int i) { - 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) -{ - 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 +125,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 +138,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 +218,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); @@ -426,20 +227,30 @@ void NeighborKokkos::build(int topoflag) template void NeighborKokkos::build_kokkos(int topoflag) { + if (style != BIN) + error->all(FLERR,"KOKKOS package only supports 'bin' neighbor lists"); + 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 +282,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 +322,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 +345,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 +358,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; @@ -606,38 +376,22 @@ void NeighborKokkos::build_topology_kokkos() { k_anglelist.modify(); k_dihedrallist.modify(); k_improperlist.modify(); - - // Transfer topology neighbor lists to Host for non-Kokkos styles - - if (force->bond && force->bond->execution_space == Host) - k_bondlist.sync(); - if (force->angle && force->angle->execution_space == Host) - k_anglelist.sync(); - if (force->dihedral && force->dihedral->execution_space == Host) - k_dihedrallist.sync(); - if (force->improper && force->improper->execution_space == Host) - k_improperlist.sync(); - - } else { + } else { neighbond_host.build_topology_kk(); - + k_bondlist = neighbond_host.k_bondlist; k_anglelist = neighbond_host.k_anglelist; k_dihedrallist = neighbond_host.k_dihedrallist; k_improperlist = neighbond_host.k_improperlist; - + k_bondlist.sync(); k_anglelist.sync(); k_dihedrallist.sync(); k_improperlist.sync(); - + k_bondlist.modify(); k_anglelist.modify(); k_dihedrallist.modify(); 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_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp new file mode 100644 index 0000000000..f987304452 --- /dev/null +++ b/src/KOKKOS/npair_kokkos.cpp @@ -0,0 +1,746 @@ +/* -*- 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. +------------------------------------------------------------------------- */ + +#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 +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_ex1_group; + k_ex1_bit = neighborKK->k_ex1_group; + k_ex2_bit = neighborKK->k_ex1_group; + 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) + nall += atom->nghost; + list->grow(nall); + + NeighborKokkosExecute + data(*list, + k_cutneighsq.view(), + k_bincount.view(), + k_bins.view(), + nstencil, + k_stencil.view(), + k_stencilxyz.view(), + nlocal, + 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(); + atomKK->sync(Device,X_MASK|TYPE_MASK|MASK_MASK|MOLECULE_MASK|TAG_MASK|SPECIAL_MASK); + + 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]; + + 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); +#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; +#endif + +if (GHOST) { + NPairKokkosBuildFunctorGhost f(data,atoms_per_bin * 5 * sizeof(X_FLOAT) * factor); + Kokkos::parallel_for(nall, f); +} else { + 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 { + 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 + } +} + 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; + } + } + + if (GHOST) { + list->inum = atom->nlocal; + list->gnum = nall - atom->nlocal; + } else { + list->inum = nall; + list->gnum = 0; + } + + list->k_ilist.template modify(); +} + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +int NeighborKokkosExecute::find_special(const int &i, const int &j) const +{ + const int n1 = nspecial(i,0); + const int n2 = nspecial(i,1); + const int n3 = nspecial(i,2); + + for (int k = 0; k < n3; k++) { + if (special(i,k) == tag(j)) { + if (k < n1) { + if (special_flag[1] == 0) return -1; + else if (special_flag[1] == 1) return 0; + else return 1; + } else if (k < 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; +}; + +/* ---------------------------------------------------------------------- */ + +template +KOKKOS_INLINE_FUNCTION +int NeighborKokkosExecute::exclusion(const int &i,const int &j, + const int &itype,const int &jtype) 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; +} + +/* ---------------------------------------------------------------------- */ + +template template +void NeighborKokkosExecute:: + build_Item(const int &i) const +{ + /* if necessary, goto next page and add pages */ + int n = 0; + int which = 0; + int moltemplate; + if (molecular == 2) moltemplate = 1; + else moltemplate = 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 typename ArrayTypes::t_int_1d_const_um stencil + = d_stencil; + + // loop over all bins in neighborhood (includes ibin) + if(HalfNeigh) + for(int m = 0; m < c_bincount(ibin); m++) { + const int j = c_bins(ibin,m); + 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 && !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; + if(exclude && exclusion(i,j,itype,jtype)) continue; + + const X_FLOAT delx = xtmp - x(j, 0); + const X_FLOAT dely = ytmp - x(j, 1); + const X_FLOAT delz = ztmp - x(j, 2); + const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; + if(rsq <= cutneighsq(itype,jtype)) { + if (molecular) { + if (!moltemplate) + which = find_special(i,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){ + if(n 0) { + if(n::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 && !Newton && (j < i)) continue; + if(!HalfNeigh && j==i) continue; + if(exclude && exclusion(i,j,itype,jtype)) continue; + + const X_FLOAT delx = xtmp - x(j, 0); + const X_FLOAT dely = ytmp - x(j, 1); + const X_FLOAT delz = ztmp - x(j, 2); + const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; + + if(rsq <= cutneighsq(itype,jtype)) { + if (molecular) { + if (!moltemplate) + which = NeighborKokkosExecute::find_special(i,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){ + if(n 0) { + if(n= neigh_list.maxneighs) { + resize() = 1; + + if(n >= new_maxneighs()) new_maxneighs() = n; + } + neigh_list.d_ilist(i) = i; +} + +/* ---------------------------------------------------------------------- */ + +#ifdef KOKKOS_HAVE_CUDA +extern __shared__ X_FLOAT sharedmem[]; + +/* ---------------------------------------------------------------------- */ + +template template +__device__ inline +void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPolicy::member_type dev) const +{ + /* loop over atoms in i's bin, + */ + const int atoms_per_bin = c_bins.dimension_1(); + const int BINS_PER_TEAM = dev.team_size()/atoms_per_bin<1?1:dev.team_size()/atoms_per_bin; + const int TEAMS_PER_BIN = atoms_per_bin/dev.team_size()<1?1:atoms_per_bin/dev.team_size(); + const int MY_BIN = dev.team_rank()/atoms_per_bin; + + const int ibin = dev.league_rank()*BINS_PER_TEAM+MY_BIN; + + if(ibin >=c_bincount.dimension_0()) return; + X_FLOAT* other_x = sharedmem; + other_x = other_x + 5*atoms_per_bin*MY_BIN; + + int* other_id = (int*) &other_x[4 * atoms_per_bin]; + + int bincount_current = c_bincount[ibin]; + + for(int kk = 0; kk < TEAMS_PER_BIN; kk++) { + const int MY_II = dev.team_rank()%atoms_per_bin+kk*dev.team_size(); + const int i = MY_II < bincount_current ? c_bins(ibin, MY_II) : -1; + /* if necessary, goto next page and add pages */ + + int n = 0; + + X_FLOAT xtmp; + X_FLOAT ytmp; + X_FLOAT ztmp; + int itype; + const AtomNeighbors neighbors_i = neigh_list.get_neighbors((i>=0&&i= 0) { + xtmp = x(i, 0); + ytmp = x(i, 1); + ztmp = x(i, 2); + itype = type(i); + other_x[MY_II] = xtmp; + other_x[MY_II + atoms_per_bin] = ytmp; + other_x[MY_II + 2 * atoms_per_bin] = ztmp; + other_x[MY_II + 3 * atoms_per_bin] = itype; + } + other_id[MY_II] = i; + int test = (__syncthreads_count(i >= 0 && i <= nlocal) == 0); + + if(test) return; + + if(i >= 0 && i < nlocal) { + #pragma unroll 4 + for(int m = 0; m < bincount_current; m++) { + int j = other_id[m]; + const int jtype = other_x[m + 3 * atoms_per_bin]; + + //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 && !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; + if(exclude && exclusion(i,j,itype,jtype)) continue; + const X_FLOAT delx = xtmp - other_x[m]; + const X_FLOAT dely = ytmp - other_x[m + atoms_per_bin]; + const X_FLOAT delz = ztmp - other_x[m + 2 * atoms_per_bin]; + const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; + + if(rsq <= cutneighsq(itype,jtype)) { + if (molecular) { + int which = 0; + if (!moltemplate) + which = NeighborKokkosExecute::find_special(i,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){ + if(n 0) { + if(n::t_int_1d_const_um stencil + = d_stencil; + for(int k = 0; k < nstencil; k++) { + const int jbin = ibin + stencil[k]; + + if(ibin == jbin) continue; + + bincount_current = c_bincount[jbin]; + int j = MY_II < bincount_current ? c_bins(jbin, MY_II) : -1; + + if(j >= 0) { + other_x[MY_II] = x(j, 0); + other_x[MY_II + atoms_per_bin] = x(j, 1); + other_x[MY_II + 2 * atoms_per_bin] = x(j, 2); + other_x[MY_II + 3 * atoms_per_bin] = type(j); + } + + other_id[MY_II] = j; + + __syncthreads(); + + if(i >= 0 && i < nlocal) { + #pragma unroll 8 + for(int m = 0; m < bincount_current; m++) { + const int j = other_id[m]; + const int jtype = other_x[m + 3 * atoms_per_bin]; + + //if(HalfNeigh && (j < i)) continue; + if(HalfNeigh && !Newton && (j < i)) continue; + if(!HalfNeigh && j==i) continue; + if(exclude && exclusion(i,j,itype,jtype)) continue; + + const X_FLOAT delx = xtmp - other_x[m]; + const X_FLOAT dely = ytmp - other_x[m + atoms_per_bin]; + const X_FLOAT delz = ztmp - other_x[m + 2 * atoms_per_bin]; + const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; + + if(rsq <= cutneighsq(itype,jtype)) { + if (molecular) { + int which = 0; + if (!moltemplate) + which = NeighborKokkosExecute::find_special(i,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){ + if(n 0) { + if(n= 0 && i < nlocal) { + neigh_list.d_numneigh(i) = n; + neigh_list.d_ilist(i) = i; + } + + if(n >= neigh_list.maxneighs) { + resize() = 1; + + if(n >= new_maxneighs()) new_maxneighs() = n; + } + } +} +#endif + +/* ---------------------------------------------------------------------- */ + +template template +void NeighborKokkosExecute:: + build_Item_Ghost(const int &i) const +{ + /* if necessary, goto next page and add pages */ + int n = 0; + int which = 0; + int moltemplate; + if (molecular == 2) moltemplate = 1; + else moltemplate = 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 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 + // skip i = j + // no molecular test when i = ghost atom + + if (i < nlocal) { + const int ibin = coord2bin(xtmp, ytmp, ztmp); + 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); + + if (HalfNeigh && j <= i) continue; + else if (j == i) continue; + + const int jtype = type[j]; + if(exclude && exclusion(i,j,itype,jtype)) continue; + + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const X_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq <= cutneighsq(itype,jtype)) { + if (molecular) { + if (!moltemplate) + which = find_special(i,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){ + if(n 0) { + if(n= mbinx || + ybin2 < 0 || ybin2 >= mbiny || + zbin2 < 0 || zbin2 >= mbinz) continue; + const int jbin = ibin + stencil[k]; + for(int m = 0; m < c_bincount(jbin); m++) { + const int j = c_bins(jbin,m); + + if (HalfNeigh && j <= i) continue; + else if (j == i) continue; + + const int jtype = type[j]; + if(exclude && exclusion(i,j,itype,jtype)) continue; + + const X_FLOAT delx = xtmp - x(j,0); + const X_FLOAT dely = ytmp - x(j,1); + const X_FLOAT delz = ztmp - x(j,2); + const X_FLOAT rsq = delx*delx + dely*dely + delz*delz; + + if (rsq <= cutneighsq(itype,jtype)) { + if(n= neigh_list.maxneighs) { + resize() = 1; + + if(n >= new_maxneighs()) new_maxneighs() = n; + } + neigh_list.d_ilist(i) = i; +} + +} + +namespace LAMMPS_NS { +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; +#ifdef KOKKOS_HAVE_CUDA +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; +template class NPairKokkos; +#endif +} diff --git a/src/KOKKOS/npair_kokkos.h b/src/KOKKOS/npair_kokkos.h new file mode 100644 index 0000000000..666508a22d --- /dev/null +++ b/src/KOKKOS/npair_kokkos.h @@ -0,0 +1,435 @@ +/* -*- 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; + int nex_type; + int maxex_type; + + int nex_group; + int maxex_group; + + int nex_mol; + int maxex_mol; + + // 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 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; + + // 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 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), + 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),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; + +#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..342aa8faec 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 @@ -126,26 +125,26 @@ void PairTersoffKokkos::setup_params() for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k <= n; k++) { - m = elem2param[map[i]][map[j]][map[k]]; - k_params.h_view(i,j,k).powerm = params[m].powerm; - k_params.h_view(i,j,k).gamma = params[m].gamma; - k_params.h_view(i,j,k).lam3 = params[m].lam3; - k_params.h_view(i,j,k).c = params[m].c; - k_params.h_view(i,j,k).d = params[m].d; - k_params.h_view(i,j,k).h = params[m].h; - k_params.h_view(i,j,k).powern = params[m].powern; - k_params.h_view(i,j,k).beta = params[m].beta; - k_params.h_view(i,j,k).lam2 = params[m].lam2; - k_params.h_view(i,j,k).bigb = params[m].bigb; - k_params.h_view(i,j,k).bigr = params[m].bigr; - k_params.h_view(i,j,k).bigd = params[m].bigd; - k_params.h_view(i,j,k).lam1 = params[m].lam1; - k_params.h_view(i,j,k).biga = params[m].biga; - k_params.h_view(i,j,k).cutsq = params[m].cutsq; - k_params.h_view(i,j,k).c1 = params[m].c1; - k_params.h_view(i,j,k).c2 = params[m].c2; - k_params.h_view(i,j,k).c3 = params[m].c3; - k_params.h_view(i,j,k).c4 = params[m].c4; + m = elem2param[i-1][j-1][k-1]; + k_params.h_view(i,j,k).powerm = params[m].powerm; + k_params.h_view(i,j,k).gamma = params[m].gamma; + k_params.h_view(i,j,k).lam3 = params[m].lam3; + k_params.h_view(i,j,k).c = params[m].c; + k_params.h_view(i,j,k).d = params[m].d; + k_params.h_view(i,j,k).h = params[m].h; + k_params.h_view(i,j,k).powern = params[m].powern; + k_params.h_view(i,j,k).beta = params[m].beta; + k_params.h_view(i,j,k).lam2 = params[m].lam2; + k_params.h_view(i,j,k).bigb = params[m].bigb; + k_params.h_view(i,j,k).bigr = params[m].bigr; + k_params.h_view(i,j,k).bigd = params[m].bigd; + k_params.h_view(i,j,k).lam1 = params[m].lam1; + k_params.h_view(i,j,k).biga = params[m].biga; + k_params.h_view(i,j,k).cutsq = params[m].cutsq; + k_params.h_view(i,j,k).c1 = params[m].c1; + k_params.h_view(i,j,k).c2 = params[m].c2; + k_params.h_view(i,j,k).c3 = params[m].c3; + k_params.h_view(i,j,k).c4 = params[m].c4; } k_params.template modify(); diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 3406c607f3..95da030b56 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 @@ -125,27 +124,27 @@ void PairTersoffMODKokkos::setup_params() for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k <= n; k++) { - m = elem2param[map[i]][map[j]][map[k]]; - k_params.h_view(i,j,k).powerm = params[m].powerm; - k_params.h_view(i,j,k).lam3 = params[m].lam3; - k_params.h_view(i,j,k).h = params[m].h; - k_params.h_view(i,j,k).powern = params[m].powern; - k_params.h_view(i,j,k).beta = params[m].beta; - k_params.h_view(i,j,k).lam2 = params[m].lam2; - k_params.h_view(i,j,k).bigb = params[m].bigb; - k_params.h_view(i,j,k).bigr = params[m].bigr; - k_params.h_view(i,j,k).bigd = params[m].bigd; - k_params.h_view(i,j,k).lam1 = params[m].lam1; - k_params.h_view(i,j,k).biga = params[m].biga; - k_params.h_view(i,j,k).cutsq = params[m].cutsq; - k_params.h_view(i,j,k).c1 = params[m].c1; - k_params.h_view(i,j,k).c2 = params[m].c2; - k_params.h_view(i,j,k).c3 = params[m].c3; - k_params.h_view(i,j,k).c4 = params[m].c4; - k_params.h_view(i,j,k).c5 = params[m].c5; - k_params.h_view(i,j,k).ca1 = params[m].ca1; - k_params.h_view(i,j,k).ca4 = params[m].ca4; - k_params.h_view(i,j,k).powern_del = params[m].powern_del; + m = elem2param[i-1][j-1][k-1]; + k_params.h_view(i,j,k).powerm = params[m].powerm; + k_params.h_view(i,j,k).lam3 = params[m].lam3; + k_params.h_view(i,j,k).h = params[m].h; + k_params.h_view(i,j,k).powern = params[m].powern; + k_params.h_view(i,j,k).beta = params[m].beta; + k_params.h_view(i,j,k).lam2 = params[m].lam2; + k_params.h_view(i,j,k).bigb = params[m].bigb; + k_params.h_view(i,j,k).bigr = params[m].bigr; + k_params.h_view(i,j,k).bigd = params[m].bigd; + k_params.h_view(i,j,k).lam1 = params[m].lam1; + k_params.h_view(i,j,k).biga = params[m].biga; + k_params.h_view(i,j,k).cutsq = params[m].cutsq; + k_params.h_view(i,j,k).c1 = params[m].c1; + k_params.h_view(i,j,k).c2 = params[m].c2; + k_params.h_view(i,j,k).c3 = params[m].c3; + k_params.h_view(i,j,k).c4 = params[m].c4; + k_params.h_view(i,j,k).c5 = params[m].c5; + k_params.h_view(i,j,k).ca1 = params[m].ca1; + k_params.h_view(i,j,k).ca4 = params[m].ca4; + k_params.h_view(i,j,k).powern_del = params[m].powern_del; } k_params.template modify(); diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index 07341911bd..a9cc1d1730 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 @@ -136,30 +135,30 @@ void PairTersoffZBLKokkos::setup_params() for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k <= n; k++) { - m = elem2param[map[i]][map[j]][map[k]]; - k_params.h_view(i,j,k).powerm = params[m].powerm; - k_params.h_view(i,j,k).gamma = params[m].gamma; - k_params.h_view(i,j,k).lam3 = params[m].lam3; - k_params.h_view(i,j,k).c = params[m].c; - k_params.h_view(i,j,k).d = params[m].d; - k_params.h_view(i,j,k).h = params[m].h; - k_params.h_view(i,j,k).powern = params[m].powern; - k_params.h_view(i,j,k).beta = params[m].beta; - k_params.h_view(i,j,k).lam2 = params[m].lam2; - k_params.h_view(i,j,k).bigb = params[m].bigb; - k_params.h_view(i,j,k).bigr = params[m].bigr; - k_params.h_view(i,j,k).bigd = params[m].bigd; - k_params.h_view(i,j,k).lam1 = params[m].lam1; - k_params.h_view(i,j,k).biga = params[m].biga; - k_params.h_view(i,j,k).cutsq = params[m].cutsq; - k_params.h_view(i,j,k).c1 = params[m].c1; - k_params.h_view(i,j,k).c2 = params[m].c2; - k_params.h_view(i,j,k).c3 = params[m].c3; - k_params.h_view(i,j,k).c4 = params[m].c4; - k_params.h_view(i,j,k).Z_i = params[m].Z_i; - k_params.h_view(i,j,k).Z_j = params[m].Z_j; - k_params.h_view(i,j,k).ZBLcut = params[m].ZBLcut; - k_params.h_view(i,j,k).ZBLexpscale = params[m].ZBLexpscale; + m = elem2param[i-1][j-1][k-1]; + k_params.h_view(i,j,k).powerm = params[m].powerm; + k_params.h_view(i,j,k).gamma = params[m].gamma; + k_params.h_view(i,j,k).lam3 = params[m].lam3; + k_params.h_view(i,j,k).c = params[m].c; + k_params.h_view(i,j,k).d = params[m].d; + k_params.h_view(i,j,k).h = params[m].h; + k_params.h_view(i,j,k).powern = params[m].powern; + k_params.h_view(i,j,k).beta = params[m].beta; + k_params.h_view(i,j,k).lam2 = params[m].lam2; + k_params.h_view(i,j,k).bigb = params[m].bigb; + k_params.h_view(i,j,k).bigr = params[m].bigr; + k_params.h_view(i,j,k).bigd = params[m].bigd; + k_params.h_view(i,j,k).lam1 = params[m].lam1; + k_params.h_view(i,j,k).biga = params[m].biga; + k_params.h_view(i,j,k).cutsq = params[m].cutsq; + k_params.h_view(i,j,k).c1 = params[m].c1; + k_params.h_view(i,j,k).c2 = params[m].c2; + k_params.h_view(i,j,k).c3 = params[m].c3; + k_params.h_view(i,j,k).c4 = params[m].c4; + k_params.h_view(i,j,k).Z_i = params[m].Z_i; + k_params.h_view(i,j,k).Z_j = params[m].Z_j; + k_params.h_view(i,j,k).ZBLcut = params[m].ZBLcut; + k_params.h_view(i,j,k).ZBLexpscale = params[m].ZBLexpscale; } k_params.template modify(); diff --git a/src/KOKKOS/region_block_kokkos.h b/src/KOKKOS/region_block_kokkos.h index 19b3204973..a8c9520298 100644 --- a/src/KOKKOS/region_block_kokkos.h +++ b/src/KOKKOS/region_block_kokkos.h @@ -33,10 +33,10 @@ template class RegBlockKokkos : public RegBlock { friend class FixPour; - public: typedef DeviceType device_type; typedef ArrayTypes AT; + public: RegBlockKokkos(class LAMMPS *, int, char **); ~RegBlockKokkos(); void match_all_kokkos(int, DAT::t_int_1d); diff --git a/src/finish.cpp b/src/finish.cpp index 0d767b42cd..f305d04346 100644 --- a/src/finish.cpp +++ b/src/finish.cpp @@ -630,22 +630,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; @@ -675,23 +670,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; @@ -865,7 +856,7 @@ void mpi_timings(const char *label, Timer *t, enum Timer::ttype tt, time_cpu = tmp/nprocs*100.0; // % variance from the average as measure of load imbalance - if ((time_sq/time - time) > 1.0e-10) + if (time > 1.0e-10) time_sq = sqrt(time_sq/time - time)*100.0; else time_sq = 0.0; @@ -917,7 +908,7 @@ void omp_times(FixOMP *fix, const char *label, enum Timer::ttype which, time_std /= nthreads; time_total /= nthreads; - if ((time_std/time_avg -time_avg) > 1.0e-10) + if (time_avg > 1.0e-10) time_std = sqrt(time_std/time_avg - time_avg)*100.0; else time_std = 0.0; diff --git a/src/neigh_list.cpp b/src/neigh_list.cpp index dfab9b023a..f8d496fc6b 100644 --- a/src/neigh_list.cpp +++ b/src/neigh_list.cpp @@ -67,6 +67,11 @@ NeighList::NeighList(LAMMPS *lmp) : Pointers(lmp) ipage = NULL; dpage = NULL; + // Kokkos package + + kokkos = 0; + execution_space = Host; + // USER-DPD package ndxAIR_ssa = NULL; diff --git a/src/neigh_list.h b/src/neigh_list.h index d3bde212c2..3b6a4d6760 100644 --- a/src/neigh_list.h +++ b/src/neigh_list.h @@ -69,6 +69,11 @@ 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 uint16_t (*ndxAIR_ssa)[8]; // for each atom, last neighbor index of each AIR @@ -80,7 +85,6 @@ class NeighList : protected Pointers { void post_constructor(class NeighRequest *); void setup_pages(int, int); // setup page data structures void grow(int,int); // grow all data structs - void stencil_allocate(int, int); // allocate stencil arrays void print_attributes(); // debug routine int get_maxlocal() {return maxatom;} bigint memory_usage(); diff --git a/src/neighbor.cpp b/src/neighbor.cpp index e58fc7126e..f27376cb2a 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -621,8 +621,7 @@ void Neighbor::init_pair() delete [] neigh_stencil; delete [] neigh_pair; - if (lmp->kokkos) nlist = init_lists_kokkos(); - else nlist = nrequest; + nlist = nrequest; lists = new NeighList*[nrequest]; neigh_bin = new NBin*[nrequest]; @@ -634,11 +633,10 @@ void Neighbor::init_pair() // 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) { - lists[i] = NULL; - continue; - } - lists[i] = new NeighList(lmp); + if (requests[i]->kokkos_host || requests[i]->kokkos_device) + create_kokkos_list(i); + else + lists[i] = new NeighList(lmp); lists[i]->index = i; if (requests[i]->pair) { @@ -680,10 +678,8 @@ void Neighbor::init_pair() // would be useful when reax/c used in hybrid mode, e.g. with airebo for (i = 0; i < nrequest; i++) { - if (lists[i] == NULL) continue; // Kokkos if (requests[i]->pair && requests[i]->half && requests[i]->newton != 2) { for (j = 0; j < nrequest; j++) { - if (lists[j] == NULL) continue; // Kokkos if (requests[j]->full && requests[j]->occasional == 0 && !requests[j]->skip && !requests[j]->copy) break; } @@ -708,10 +704,8 @@ void Neighbor::init_pair() // for 1st or 2nd check, parent can be copy list or pair or fix for (i = 0; i < nrequest; i++) { - if (lists[i] == NULL) continue; // Kokkos if (!requests[i]->fix && !requests[i]->compute) continue; for (j = 0; j < nrequest; j++) { - if (lists[j] == NULL) continue; // Kokkos if (requests[i]->half && requests[j]->pair && !requests[j]->skip && requests[j]->half && !requests[j]->copy) break; @@ -733,7 +727,6 @@ void Neighbor::init_pair() continue; } for (j = 0; j < nrequest; j++) { - if (lists[j] == NULL) continue; // Kokkos if (requests[i]->half && requests[j]->pair && !requests[j]->skip && requests[j]->full && !requests[j]->copy) break; @@ -844,7 +837,6 @@ void Neighbor::init_pair() int dnummax = 0; for (i = 0; i < nlist; i++) { - if (lists[i] == NULL) continue; // Kokkos if (lists[i]->copy) continue; lists[i]->setup_pages(pgsize,oneatom); dnummax = MAX(dnummax,lists[i]->dnum); @@ -864,14 +856,8 @@ void Neighbor::init_pair() // also Kokkos list initialization int maxatom = atom->nmax; - for (i = 0; i < nlist; i++) { - if (lists[i]) { - if (neigh_pair[i] && !lists[i]->copy) lists[i]->grow(maxatom,maxatom); - } else { - init_list_flags1_kokkos(i); - init_list_grow_kokkos(i); - } - } + 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 @@ -885,10 +871,8 @@ void Neighbor::init_pair() plist = new int[nlist]; for (i = 0; i < nlist; i++) { - if (lists[i]) { - if (lists[i]->occasional == 0 && lists[i]->pair_method) - plist[npair_perpetual++] = i; - } else init_list_flags2_kokkos(i); + if (lists[i]->occasional == 0 && lists[i]->pair_method) + plist[npair_perpetual++] = i; } for (i = 0; i < nstencil; i++) { @@ -910,7 +894,6 @@ void Neighbor::init_pair() while (!done) { done = 1; for (i = 0; i < npair_perpetual; i++) { - if (!lists[plist[i]]) continue; // Kokkos check ptr = NULL; if (lists[plist[i]]->listcopy) ptr = lists[plist[i]]->listcopy; if (lists[plist[i]]->listskip) ptr = lists[plist[i]]->listskip; @@ -1154,15 +1137,14 @@ void Neighbor::print_pairwise_info() 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"; - else if (requests[i]->full_cluster) kind = "full/cluster"; // Kokkos - fprintf(out," kind: %s",kind); - 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) @@ -1237,13 +1219,17 @@ int Neighbor::choose_bin(NeighRequest *rq) // 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; + int ssaflag,intelflag,kokkos_device_flag,kokkos_host_flag; - ssaflag = intelflag = 0; + 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 @@ -1254,6 +1240,8 @@ int Neighbor::choose_bin(NeighRequest *rq) 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; } @@ -1308,6 +1296,7 @@ int Neighbor::choose_stencil(NeighRequest *rq) 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 @@ -1381,16 +1370,18 @@ int Neighbor::choose_pair(NeighRequest *rq) // 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; + 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 = 0; + ompflag = intelflag = kokkos_device_flag = kokkos_host_flag = 0; if (rq->copy) copyflag = NP_COPY; if (rq->skip) skipflag = NP_SKIP; @@ -1420,6 +1411,8 @@ int Neighbor::choose_pair(NeighRequest *rq) 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; @@ -1460,6 +1453,8 @@ int Neighbor::choose_pair(NeighRequest *rq) 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; @@ -1802,6 +1797,7 @@ void Neighbor::build_one(class NeighList *mylist, int preflag) ns->create(); } + // build the list np->build_setup(); diff --git a/src/neighbor.h b/src/neighbor.h index 9655cca545..eb603ad84f 100644 --- a/src/neighbor.h +++ b/src/neighbor.h @@ -201,7 +201,7 @@ class Neighbor : protected Pointers { void init_styles(); void init_pair(); - void init_topology(); + virtual void init_topology(); void print_pairwise_info(); void requests_new2old(); @@ -220,18 +220,17 @@ class Neighbor : protected Pointers { int copymode; 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 create_kokkos_list(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) {} }; 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; @@ -266,6 +265,8 @@ namespace NeighConst { 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; } } diff --git a/src/npair.h b/src/npair.h index 70fcc5c452..a6440faddf 100644 --- a/src/npair.h +++ b/src/npair.h @@ -31,7 +31,7 @@ class NPair : protected Pointers { NPair(class LAMMPS *); virtual ~NPair() {} - void copy_neighbor_info(); + virtual void copy_neighbor_info(); void build_setup(); virtual void build(class NeighList *) = 0; @@ -94,8 +94,8 @@ class NPair : protected Pointers { // methods for all NPair variants void copy_bin_setup_info(); - void copy_bin_info(); - void copy_stencil_info(); + virtual void copy_bin_info(); + virtual void copy_stencil_info(); int exclusion(int, int, int, int, int *, tagint *) const; // test for pair exclusion diff --git a/src/nstencil.h b/src/nstencil.h index b9c6dd58fb..8672584a19 100644 --- a/src/nstencil.h +++ b/src/nstencil.h @@ -37,7 +37,7 @@ class NStencil : protected Pointers { NStencil(class LAMMPS *); virtual ~NStencil(); void copy_neighbor_info(); - void create_setup(); + virtual void create_setup(); bigint memory_usage(); virtual void create() = 0; From 9b48c49f8348560037c98fb38b86b346838d6936 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Thu, 8 Dec 2016 09:18:55 -0700 Subject: [PATCH 13/22] Removing used Kokkos file --- src/KOKKOS/neigh_full_kokkos.h | 875 --------------------------------- 1 file changed, 875 deletions(-) delete mode 100644 src/KOKKOS/neigh_full_kokkos.h diff --git a/src/KOKKOS/neigh_full_kokkos.h b/src/KOKKOS/neigh_full_kokkos.h deleted file mode 100644 index 9125b5fbe2..0000000000 --- a/src/KOKKOS/neigh_full_kokkos.h +++ /dev/null @@ -1,875 +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. -------------------------------------------------------------------------- */ - -#include "atom_kokkos.h" -#include "atom_masks.h" -#include "domain_kokkos.h" - -namespace LAMMPS_NS { - -/* ---------------------------------------------------------------------- */ - -template -void NeighborKokkos::full_bin_kokkos(NeighListKokkos *list) -{ - const int nlocal = includegroup?atom->nfirst:atom->nlocal; - int nall = nlocal; - if (GHOST) - nall += atom->nghost; - list->grow(nall); - - NeighborKokkosExecute - data(*list, - k_cutneighsq.view(), - k_bincount.view(), - k_bins.view(),nlocal, - 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(); - 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); - 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); -#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; -#endif - -if (GHOST) { - NeighborKokkosBuildFunctorGhost 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); -#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); -#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; - } - } - - if (GHOST) { - list->inum = atom->nlocal; - list->gnum = nall - atom->nlocal; - } else { - list->inum = nall; - list->gnum = 0; - } - - list->k_ilist.template modify(); -} - -/* ---------------------------------------------------------------------- */ - -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 -{ - const int n1 = nspecial(i,0); - const int n2 = nspecial(i,1); - const int n3 = nspecial(i,2); - - for (int k = 0; k < n3; k++) { - if (special(i,k) == tag(j)) { - if (k < n1) { - if (special_flag[1] == 0) return -1; - else if (special_flag[1] == 1) return 0; - else return 1; - } else if (k < 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; -}; - -/* ---------------------------------------------------------------------- */ - -template -KOKKOS_INLINE_FUNCTION -int NeighborKokkosExecute::exclusion(const int &i,const int &j, - const int &itype,const int &jtype) 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; -} - -/* ---------------------------------------------------------------------- */ - -template template -void NeighborKokkosExecute:: - build_Item(const int &i) const -{ - /* if necessary, goto next page and add pages */ - int n = 0; - int which = 0; - int moltemplate; - if (molecular == 2) moltemplate = 1; - else moltemplate = 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; - - // loop over all bins in neighborhood (includes ibin) - if(HalfNeigh) - for(int m = 0; m < c_bincount(ibin); m++) { - const int j = c_bins(ibin,m); - 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) && - ((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; - if(exclude && exclusion(i,j,itype,jtype)) continue; - - const X_FLOAT delx = xtmp - x(j, 0); - const X_FLOAT dely = ytmp - x(j, 1); - const X_FLOAT delz = ztmp - x(j, 2); - const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; - if(rsq <= cutneighsq(itype,jtype)) { - if (molecular) { - if (!moltemplate) - which = find_special(i,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){ - if(n 0) { - if(n::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 && j==i) continue; - if(exclude && exclusion(i,j,itype,jtype)) continue; - - const X_FLOAT delx = xtmp - x(j, 0); - const X_FLOAT dely = ytmp - x(j, 1); - const X_FLOAT delz = ztmp - x(j, 2); - const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; - - if(rsq <= cutneighsq(itype,jtype)) { - if (molecular) { - if (!moltemplate) - which = find_special(i,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){ - if(n 0) { - if(n= neigh_list.maxneighs) { - resize() = 1; - - if(n >= new_maxneighs()) new_maxneighs() = n; - } - neigh_list.d_ilist(i) = i; -} - -#ifdef KOKKOS_HAVE_CUDA -extern __shared__ X_FLOAT sharedmem[]; - -/* ---------------------------------------------------------------------- */ - -template template -__device__ inline -void NeighborKokkosExecute::build_ItemCuda(typename Kokkos::TeamPolicy::member_type dev) const -{ - /* loop over atoms in i's bin, - */ - const int atoms_per_bin = c_bins.dimension_1(); - const int BINS_PER_TEAM = dev.team_size()/atoms_per_bin<1?1:dev.team_size()/atoms_per_bin; - const int TEAMS_PER_BIN = atoms_per_bin/dev.team_size()<1?1:atoms_per_bin/dev.team_size(); - const int MY_BIN = dev.team_rank()/atoms_per_bin; - - const int ibin = dev.league_rank()*BINS_PER_TEAM+MY_BIN; - - if(ibin >=c_bincount.dimension_0()) return; - X_FLOAT* other_x = sharedmem; - other_x = other_x + 5*atoms_per_bin*MY_BIN; - - int* other_id = (int*) &other_x[4 * atoms_per_bin]; - - int bincount_current = c_bincount[ibin]; - - for(int kk = 0; kk < TEAMS_PER_BIN; kk++) { - const int MY_II = dev.team_rank()%atoms_per_bin+kk*dev.team_size(); - const int i = MY_II < bincount_current ? c_bins(ibin, MY_II) : -1; - /* if necessary, goto next page and add pages */ - - int n = 0; - - X_FLOAT xtmp; - X_FLOAT ytmp; - X_FLOAT ztmp; - int itype; - const AtomNeighbors neighbors_i = neigh_list.get_neighbors((i>=0&&i= 0) { - xtmp = x(i, 0); - ytmp = x(i, 1); - ztmp = x(i, 2); - itype = type(i); - other_x[MY_II] = xtmp; - other_x[MY_II + atoms_per_bin] = ytmp; - other_x[MY_II + 2 * atoms_per_bin] = ztmp; - other_x[MY_II + 3 * atoms_per_bin] = itype; - } - other_id[MY_II] = i; - int test = (__syncthreads_count(i >= 0 && i <= nlocal) == 0); - - if(test) return; - - if(i >= 0 && i < nlocal) { - #pragma unroll 4 - for(int m = 0; m < bincount_current; m++) { - int j = other_id[m]; - const int jtype = other_x[m + 3 * atoms_per_bin]; - - //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) && ((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; - if(exclude && exclusion(i,j,itype,jtype)) continue; - const X_FLOAT delx = xtmp - other_x[m]; - const X_FLOAT dely = ytmp - other_x[m + atoms_per_bin]; - const X_FLOAT delz = ztmp - other_x[m + 2 * atoms_per_bin]; - const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; - - if(rsq <= cutneighsq(itype,jtype)) { - if (molecular) { - int which = 0; - if (!moltemplate) - which = find_special(i,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){ - if(n 0) { - if(n::t_int_1d_const_um stencil - = neigh_list.d_stencil; - for(int k = 0; k < nstencil; k++) { - const int jbin = ibin + stencil[k]; - - if(ibin == jbin) continue; - - bincount_current = c_bincount[jbin]; - int j = MY_II < bincount_current ? c_bins(jbin, MY_II) : -1; - - if(j >= 0) { - other_x[MY_II] = x(j, 0); - other_x[MY_II + atoms_per_bin] = x(j, 1); - other_x[MY_II + 2 * atoms_per_bin] = x(j, 2); - other_x[MY_II + 3 * atoms_per_bin] = type(j); - } - - other_id[MY_II] = j; - - __syncthreads(); - - if(i >= 0 && i < nlocal) { - #pragma unroll 8 - for(int m = 0; m < bincount_current; m++) { - const int j = other_id[m]; - const int jtype = other_x[m + 3 * atoms_per_bin]; - - //if(HalfNeigh && (j < i)) continue; - if(HalfNeigh && !GhostNewton && (j < i)) continue; - if(!HalfNeigh && j==i) continue; - if(exclude && exclusion(i,j,itype,jtype)) continue; - - const X_FLOAT delx = xtmp - other_x[m]; - const X_FLOAT dely = ytmp - other_x[m + atoms_per_bin]; - const X_FLOAT delz = ztmp - other_x[m + 2 * atoms_per_bin]; - const X_FLOAT rsq = delx * delx + dely * dely + delz * delz; - - if(rsq <= cutneighsq(itype,jtype)) { - if (molecular) { - int which = 0; - if (!moltemplate) - which = find_special(i,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){ - if(n 0) { - if(n= 0 && i < nlocal) { - neigh_list.d_numneigh(i) = n; - neigh_list.d_ilist(i) = i; - } - - if(n >= neigh_list.maxneighs) { - resize() = 1; - - if(n >= new_maxneighs()) new_maxneighs() = n; - } - } -} -#endif - -/* ---------------------------------------------------------------------- */ - -template template -void NeighborKokkosExecute:: - build_Item_Ghost(const int &i) const -{ - /* if necessary, goto next page and add pages */ - int n = 0; - int which = 0; - int moltemplate; - if (molecular == 2) moltemplate = 1; - else moltemplate = 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 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; - - // 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) { - const int ibin = coord2bin(xtmp, ytmp, ztmp); - 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); - - if (HalfNeigh && j <= i) continue; - else if (j == i) continue; - - const int jtype = type[j]; - if(exclude && exclusion(i,j,itype,jtype)) continue; - - const X_FLOAT delx = xtmp - x(j,0); - const X_FLOAT dely = ytmp - x(j,1); - const X_FLOAT delz = ztmp - x(j,2); - const X_FLOAT rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq(itype,jtype)) { - if (molecular) { - if (!moltemplate) - which = find_special(i,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){ - if(n 0) { - if(n= mbinx || - ybin2 < 0 || ybin2 >= mbiny || - zbin2 < 0 || zbin2 >= mbinz) continue; - const int jbin = ibin + stencil[k]; - for(int m = 0; m < c_bincount(jbin); m++) { - const int j = c_bins(jbin,m); - - if (HalfNeigh && j <= i) continue; - else if (j == i) continue; - - const int jtype = type[j]; - if(exclude && exclusion(i,j,itype,jtype)) continue; - - const X_FLOAT delx = xtmp - x(j,0); - const X_FLOAT dely = ytmp - x(j,1); - const X_FLOAT delz = ztmp - x(j,2); - const X_FLOAT rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq(itype,jtype)) { - if(n= neigh_list.maxneighs) { - resize() = 1; - - if(n >= new_maxneighs()) new_maxneighs() = n; - } - 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); -#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; -#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; -} - -} From 435421301b0b851f1b73c04885f63e2f09c20475 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 9 Dec 2016 08:37:01 -0700 Subject: [PATCH 14/22] Small tweaks to Kokkos neighbor --- src/KOKKOS/neigh_list_kokkos.h | 2 +- src/KOKKOS/neighbor_kokkos.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/KOKKOS/neigh_list_kokkos.h b/src/KOKKOS/neigh_list_kokkos.h index 393fa478a1..45e768927c 100644 --- a/src/KOKKOS/neigh_list_kokkos.h +++ b/src/KOKKOS/neigh_list_kokkos.h @@ -76,7 +76,7 @@ public: typename ArrayTypes::t_int_1d d_numneigh; // # of J neighs for each I NeighListKokkos(class LAMMPS *lmp): - NeighList(lmp) {_stride = 1; maxneighs = 16; kokkos = 1; + NeighList(lmp) {_stride = 1; maxneighs = 16; kokkos = 1; maxatoms = 0; execution_space = ExecutionSpaceFromDevice::space; }; ~NeighListKokkos() {numneigh = NULL; ilist = NULL;}; diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index ff154c9919..ae8ae82c13 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -92,6 +92,9 @@ void NeighborKokkos::init_cutneighsq_kokkos(int n) void NeighborKokkos::create_kokkos_list(int i) { + if (style != BIN) + error->all(FLERR,"KOKKOS package only supports 'bin' neighbor lists"); + if (requests[i]->kokkos_device) { lists[i] = new NeighListKokkos(lmp); device_flag = 1; @@ -227,9 +230,6 @@ void NeighborKokkos::build(int topoflag) template void NeighborKokkos::build_kokkos(int topoflag) { - if (style != BIN) - error->all(FLERR,"KOKKOS package only supports 'bin' neighbor lists"); - typedef DeviceType device_type; int i,m; From eff503e56c1f524dcf76687838c40984bec2d3e6 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 9 Dec 2016 15:39:46 -0600 Subject: [PATCH 15/22] Prevent neighbor list copies between SSA and non-SSA neighbor list requests. --- src/neighbor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/neighbor.cpp b/src/neighbor.cpp index e58fc7126e..88c62b1873 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -712,6 +712,7 @@ void Neighbor::init_pair() if (!requests[i]->fix && !requests[i]->compute) continue; for (j = 0; j < nrequest; j++) { if (lists[j] == NULL) continue; // Kokkos + if (requests[i]->ssa != requests[j]->ssa) continue; if (requests[i]->half && requests[j]->pair && !requests[j]->skip && requests[j]->half && !requests[j]->copy) break; From 5187cb97e5f15db89405df77a8355b9f59fd46b3 Mon Sep 17 00:00:00 2001 From: Tim Mattox Date: Fri, 9 Dec 2016 15:42:27 -0600 Subject: [PATCH 16/22] USER-DPD: Make fix_shardlow request its own SSA-specific neighbor list, instead of having pair_dpd_fdt* make the SSA-neighbor list request for it. Forces an "extra" list to be built, but now skip lists work properly. Maybe we can detect if skip lists won't be used, and squash the extra list. --- src/USER-DPD/fix_shardlow.cpp | 23 +++++++++++++++++++---- src/USER-DPD/fix_shardlow.h | 4 ++++ src/USER-DPD/pair_dpd_fdt.cpp | 2 -- src/USER-DPD/pair_dpd_fdt_energy.cpp | 2 -- 4 files changed, 23 insertions(+), 8 deletions(-) diff --git a/src/USER-DPD/fix_shardlow.cpp b/src/USER-DPD/fix_shardlow.cpp index 2253b11932..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); @@ -410,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 @@ -431,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/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; From 43c459ba56948da331446e3e7357691b3b95e177 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Fri, 9 Dec 2016 15:56:55 -0700 Subject: [PATCH 17/22] More changes for Kokkos neighbor --- src/KOKKOS/Install.sh | 2 ++ src/KOKKOS/nbin_kokkos.cpp | 1 + src/KOKKOS/npair_copy_kokkos.cpp | 62 ++++++++++++++++++++++++++++++++ src/KOKKOS/npair_copy_kokkos.h | 48 +++++++++++++++++++++++++ src/KOKKOS/npair_kokkos.cpp | 15 ++++---- src/KOKKOS/npair_kokkos.h | 23 ++++-------- src/neighbor.cpp | 22 +++++++++--- 7 files changed, 146 insertions(+), 27 deletions(-) create mode 100644 src/KOKKOS/npair_copy_kokkos.cpp create mode 100644 src/KOKKOS/npair_copy_kokkos.h diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index ebafb87466..7a725a021c 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -109,6 +109,8 @@ 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 diff --git a/src/KOKKOS/nbin_kokkos.cpp b/src/KOKKOS/nbin_kokkos.cpp index feec72f45a..9a73e23b42 100644 --- a/src/KOKKOS/nbin_kokkos.cpp +++ b/src/KOKKOS/nbin_kokkos.cpp @@ -116,6 +116,7 @@ void NBinKokkos::bin_atoms() k_bins = DAT::tdual_int_2d("bins", mbins, atoms_per_bin); bins = k_bins.view(); c_bins = bins; + last_bin_memory = update->ntimestep; } } } 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/npair_kokkos.cpp b/src/KOKKOS/npair_kokkos.cpp index f987304452..fd32cd463e 100644 --- a/src/KOKKOS/npair_kokkos.cpp +++ b/src/KOKKOS/npair_kokkos.cpp @@ -51,9 +51,9 @@ void NPairKokkos::copy_neighbor_info() 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_ex1_group; - k_ex1_bit = neighborKK->k_ex1_group; - k_ex2_bit = 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; } @@ -135,16 +135,16 @@ void NPairKokkos::build(NeighList *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, @@ -161,6 +161,8 @@ void NPairKokkos::build(NeighList *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); data.special_flag[0] = special_flag[0]; @@ -415,6 +417,7 @@ void NeighborKokkosExecute:: 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 index 666508a22d..4b77175191 100644 --- a/src/KOKKOS/npair_kokkos.h +++ b/src/KOKKOS/npair_kokkos.h @@ -75,14 +75,6 @@ class NPairKokkos : public NPair { private: int newton_pair; - int nex_type; - int maxex_type; - - int nex_group; - int maxex_group; - - int nex_mol; - int maxex_mol; // data from Neighbor class @@ -127,17 +119,14 @@ class NeighborKokkosExecute 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; @@ -204,16 +193,16 @@ class NeighborKokkosExecute 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 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 int & _maxex_group, + 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 int & _maxex_mol, + 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, @@ -229,11 +218,11 @@ class NeighborKokkosExecute 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), + exclude(_exclude),nex_type(_nex_type), ex1_type(_ex1_type),ex2_type(_ex2_type),ex_type(_ex_type), - nex_group(_nex_group),maxex_group(_maxex_group), + nex_group(_nex_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), + 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) { diff --git a/src/neighbor.cpp b/src/neighbor.cpp index f27376cb2a..81f33e2479 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -660,10 +660,8 @@ void Neighbor::init_pair() // 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++) { - if (!lists[i]) continue; + for (i = 0; i < nrequest; i++) lists[i]->post_constructor(requests[i]); - } // (B) rule: // if request = pair, half, newton != 2 @@ -680,6 +678,10 @@ void Neighbor::init_pair() 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; } @@ -706,6 +708,10 @@ void Neighbor::init_pair() 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; + if (requests[i]->half && requests[j]->pair && !requests[j]->skip && requests[j]->half && !requests[j]->copy) break; @@ -727,6 +733,10 @@ void Neighbor::init_pair() 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 (requests[i]->half && requests[j]->pair && !requests[j]->skip && requests[j]->full && !requests[j]->copy) break; @@ -1434,7 +1444,11 @@ int Neighbor::choose_pair(NeighRequest *rq) for (int i = 0; i < npclass; i++) { mask = pairmasks[i]; - if (copyflag && (mask & NP_COPY)) return i+1; + 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) { From a31b00965a818835a6c1b5d57f0c5e2e42a389ba Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 12 Dec 2016 09:18:20 -0700 Subject: [PATCH 18/22] Updating to master --- src/KOKKOS/Install.sh | 2 ++ src/KOKKOS/atom_vec_kokkos.h | 14 ++++++-- src/KOKKOS/neighbor_kokkos.cpp | 39 +++++++++++++++++---- src/KOKKOS/pair_tersoff_kokkos.cpp | 40 ++++++++++----------- src/KOKKOS/pair_tersoff_mod_kokkos.cpp | 42 +++++++++++----------- src/KOKKOS/pair_tersoff_zbl_kokkos.cpp | 48 +++++++++++++------------- src/KOKKOS/region_block_kokkos.h | 2 +- src/finish.cpp | 4 +-- 8 files changed, 114 insertions(+), 77 deletions(-) diff --git a/src/KOKKOS/Install.sh b/src/KOKKOS/Install.sh index 7a725a021c..4f1d83f29d 100644 --- a/src/KOKKOS/Install.sh +++ b/src/KOKKOS/Install.sh @@ -174,6 +174,8 @@ action pair_reax_c_kokkos.cpp pair_reax_c.cpp action pair_reax_c_kokkos.h pair_reax_c.h action pair_sw_kokkos.cpp pair_sw.cpp action pair_sw_kokkos.h pair_sw.h +action pair_vashishta_kokkos.cpp pair_vashishta.cpp +action pair_vashishta_kokkos.h pair_vashishta.h action pair_table_kokkos.cpp action pair_table_kokkos.h action pair_tersoff_kokkos.cpp pair_tersoff.cpp diff --git a/src/KOKKOS/atom_vec_kokkos.h b/src/KOKKOS/atom_vec_kokkos.h index fbeeaf96be..7ac66f1626 100644 --- a/src/KOKKOS/atom_vec_kokkos.h +++ b/src/KOKKOS/atom_vec_kokkos.h @@ -83,8 +83,13 @@ class AtomVecKokkos : public AtomVec { std::is_same::value, Kokkos::CudaHostPinnedSpace,typename ViewType::memory_space>::type, Kokkos::MemoryTraits > mirror_type; - if(buffer_size < src.capacity()) + if (buffer_size == 0) { + buffer = Kokkos::kokkos_malloc(src.capacity()); + buffer_size = src.capacity(); + } else if (buffer_size < src.capacity()) { buffer = Kokkos::kokkos_realloc(buffer,src.capacity()); + buffer_size = src.capacity(); + } return mirror_type( buffer , src.dimension_0() , src.dimension_1() , @@ -104,8 +109,13 @@ class AtomVecKokkos : public AtomVec { std::is_same::value, Kokkos::CudaHostPinnedSpace,typename ViewType::memory_space>::type, Kokkos::MemoryTraits > mirror_type; - if(buffer_size < src.capacity()) + if (buffer_size == 0) { + buffer = Kokkos::kokkos_malloc(src.capacity()*sizeof(typename ViewType::value_type)); + buffer_size = src.capacity(); + } else if (buffer_size < src.capacity()) { buffer = Kokkos::kokkos_realloc(buffer,src.capacity()*sizeof(typename ViewType::value_type)); + buffer_size = src.capacity(); + } mirror_type tmp_view( (typename ViewType::value_type*)buffer , src.dimension_0() , src.dimension_1() , diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index ae8ae82c13..970e3ad0f9 100644 --- a/src/KOKKOS/neighbor_kokkos.cpp +++ b/src/KOKKOS/neighbor_kokkos.cpp @@ -74,6 +74,19 @@ void NeighborKokkos::init() atomKK = (AtomKokkos *) atom; Neighbor::init(); + + + + + + + + + + + + + // 1st time allocation of xhold if (dist_check) @@ -358,8 +371,8 @@ void NeighborKokkos::init_topology() { normally built with pair lists, but USER-CUDA separates them ------------------------------------------------------------------------- */ -void NeighborKokkos::build_topology() { - if (device_flag) { +void NeighborKokkos::build_topology_kokkos() { + if (nlist_device) { neighbond_device.build_topology_kk(); k_bondlist = neighbond_device.k_bondlist; @@ -376,22 +389,34 @@ void NeighborKokkos::build_topology() { k_anglelist.modify(); k_dihedrallist.modify(); k_improperlist.modify(); - } else { + + // Transfer topology neighbor lists to Host for non-Kokkos styles + + if (force->bond && force->bond->execution_space == Host) + k_bondlist.sync(); + if (force->angle && force->angle->execution_space == Host) + k_anglelist.sync(); + if (force->dihedral && force->dihedral->execution_space == Host) + k_dihedrallist.sync(); + if (force->improper && force->improper->execution_space == Host) + k_improperlist.sync(); + + } else { neighbond_host.build_topology_kk(); - + k_bondlist = neighbond_host.k_bondlist; k_anglelist = neighbond_host.k_anglelist; k_dihedrallist = neighbond_host.k_dihedrallist; k_improperlist = neighbond_host.k_improperlist; - + k_bondlist.sync(); k_anglelist.sync(); k_dihedrallist.sync(); k_improperlist.sync(); - + k_bondlist.modify(); k_anglelist.modify(); k_dihedrallist.modify(); k_improperlist.modify(); } -} +} \ No newline at end of file diff --git a/src/KOKKOS/pair_tersoff_kokkos.cpp b/src/KOKKOS/pair_tersoff_kokkos.cpp index 342aa8faec..40e54df33b 100644 --- a/src/KOKKOS/pair_tersoff_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_kokkos.cpp @@ -125,26 +125,26 @@ void PairTersoffKokkos::setup_params() for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k <= n; k++) { - m = elem2param[i-1][j-1][k-1]; - k_params.h_view(i,j,k).powerm = params[m].powerm; - k_params.h_view(i,j,k).gamma = params[m].gamma; - k_params.h_view(i,j,k).lam3 = params[m].lam3; - k_params.h_view(i,j,k).c = params[m].c; - k_params.h_view(i,j,k).d = params[m].d; - k_params.h_view(i,j,k).h = params[m].h; - k_params.h_view(i,j,k).powern = params[m].powern; - k_params.h_view(i,j,k).beta = params[m].beta; - k_params.h_view(i,j,k).lam2 = params[m].lam2; - k_params.h_view(i,j,k).bigb = params[m].bigb; - k_params.h_view(i,j,k).bigr = params[m].bigr; - k_params.h_view(i,j,k).bigd = params[m].bigd; - k_params.h_view(i,j,k).lam1 = params[m].lam1; - k_params.h_view(i,j,k).biga = params[m].biga; - k_params.h_view(i,j,k).cutsq = params[m].cutsq; - k_params.h_view(i,j,k).c1 = params[m].c1; - k_params.h_view(i,j,k).c2 = params[m].c2; - k_params.h_view(i,j,k).c3 = params[m].c3; - k_params.h_view(i,j,k).c4 = params[m].c4; + m = elem2param[map[i]][map[j]][map[k]]; + k_params.h_view(i,j,k).powerm = params[m].powerm; + k_params.h_view(i,j,k).gamma = params[m].gamma; + k_params.h_view(i,j,k).lam3 = params[m].lam3; + k_params.h_view(i,j,k).c = params[m].c; + k_params.h_view(i,j,k).d = params[m].d; + k_params.h_view(i,j,k).h = params[m].h; + k_params.h_view(i,j,k).powern = params[m].powern; + k_params.h_view(i,j,k).beta = params[m].beta; + k_params.h_view(i,j,k).lam2 = params[m].lam2; + k_params.h_view(i,j,k).bigb = params[m].bigb; + k_params.h_view(i,j,k).bigr = params[m].bigr; + k_params.h_view(i,j,k).bigd = params[m].bigd; + k_params.h_view(i,j,k).lam1 = params[m].lam1; + k_params.h_view(i,j,k).biga = params[m].biga; + k_params.h_view(i,j,k).cutsq = params[m].cutsq; + k_params.h_view(i,j,k).c1 = params[m].c1; + k_params.h_view(i,j,k).c2 = params[m].c2; + k_params.h_view(i,j,k).c3 = params[m].c3; + k_params.h_view(i,j,k).c4 = params[m].c4; } k_params.template modify(); diff --git a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp index 95da030b56..dd6adb128c 100644 --- a/src/KOKKOS/pair_tersoff_mod_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_mod_kokkos.cpp @@ -124,27 +124,27 @@ void PairTersoffMODKokkos::setup_params() for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k <= n; k++) { - m = elem2param[i-1][j-1][k-1]; - k_params.h_view(i,j,k).powerm = params[m].powerm; - k_params.h_view(i,j,k).lam3 = params[m].lam3; - k_params.h_view(i,j,k).h = params[m].h; - k_params.h_view(i,j,k).powern = params[m].powern; - k_params.h_view(i,j,k).beta = params[m].beta; - k_params.h_view(i,j,k).lam2 = params[m].lam2; - k_params.h_view(i,j,k).bigb = params[m].bigb; - k_params.h_view(i,j,k).bigr = params[m].bigr; - k_params.h_view(i,j,k).bigd = params[m].bigd; - k_params.h_view(i,j,k).lam1 = params[m].lam1; - k_params.h_view(i,j,k).biga = params[m].biga; - k_params.h_view(i,j,k).cutsq = params[m].cutsq; - k_params.h_view(i,j,k).c1 = params[m].c1; - k_params.h_view(i,j,k).c2 = params[m].c2; - k_params.h_view(i,j,k).c3 = params[m].c3; - k_params.h_view(i,j,k).c4 = params[m].c4; - k_params.h_view(i,j,k).c5 = params[m].c5; - k_params.h_view(i,j,k).ca1 = params[m].ca1; - k_params.h_view(i,j,k).ca4 = params[m].ca4; - k_params.h_view(i,j,k).powern_del = params[m].powern_del; + m = elem2param[map[i]][map[j]][map[k]]; + k_params.h_view(i,j,k).powerm = params[m].powerm; + k_params.h_view(i,j,k).lam3 = params[m].lam3; + k_params.h_view(i,j,k).h = params[m].h; + k_params.h_view(i,j,k).powern = params[m].powern; + k_params.h_view(i,j,k).beta = params[m].beta; + k_params.h_view(i,j,k).lam2 = params[m].lam2; + k_params.h_view(i,j,k).bigb = params[m].bigb; + k_params.h_view(i,j,k).bigr = params[m].bigr; + k_params.h_view(i,j,k).bigd = params[m].bigd; + k_params.h_view(i,j,k).lam1 = params[m].lam1; + k_params.h_view(i,j,k).biga = params[m].biga; + k_params.h_view(i,j,k).cutsq = params[m].cutsq; + k_params.h_view(i,j,k).c1 = params[m].c1; + k_params.h_view(i,j,k).c2 = params[m].c2; + k_params.h_view(i,j,k).c3 = params[m].c3; + k_params.h_view(i,j,k).c4 = params[m].c4; + k_params.h_view(i,j,k).c5 = params[m].c5; + k_params.h_view(i,j,k).ca1 = params[m].ca1; + k_params.h_view(i,j,k).ca4 = params[m].ca4; + k_params.h_view(i,j,k).powern_del = params[m].powern_del; } k_params.template modify(); diff --git a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp index a9cc1d1730..40145dbec0 100644 --- a/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp +++ b/src/KOKKOS/pair_tersoff_zbl_kokkos.cpp @@ -135,30 +135,30 @@ void PairTersoffZBLKokkos::setup_params() for (i = 1; i <= n; i++) for (j = 1; j <= n; j++) for (k = 1; k <= n; k++) { - m = elem2param[i-1][j-1][k-1]; - k_params.h_view(i,j,k).powerm = params[m].powerm; - k_params.h_view(i,j,k).gamma = params[m].gamma; - k_params.h_view(i,j,k).lam3 = params[m].lam3; - k_params.h_view(i,j,k).c = params[m].c; - k_params.h_view(i,j,k).d = params[m].d; - k_params.h_view(i,j,k).h = params[m].h; - k_params.h_view(i,j,k).powern = params[m].powern; - k_params.h_view(i,j,k).beta = params[m].beta; - k_params.h_view(i,j,k).lam2 = params[m].lam2; - k_params.h_view(i,j,k).bigb = params[m].bigb; - k_params.h_view(i,j,k).bigr = params[m].bigr; - k_params.h_view(i,j,k).bigd = params[m].bigd; - k_params.h_view(i,j,k).lam1 = params[m].lam1; - k_params.h_view(i,j,k).biga = params[m].biga; - k_params.h_view(i,j,k).cutsq = params[m].cutsq; - k_params.h_view(i,j,k).c1 = params[m].c1; - k_params.h_view(i,j,k).c2 = params[m].c2; - k_params.h_view(i,j,k).c3 = params[m].c3; - k_params.h_view(i,j,k).c4 = params[m].c4; - k_params.h_view(i,j,k).Z_i = params[m].Z_i; - k_params.h_view(i,j,k).Z_j = params[m].Z_j; - k_params.h_view(i,j,k).ZBLcut = params[m].ZBLcut; - k_params.h_view(i,j,k).ZBLexpscale = params[m].ZBLexpscale; + m = elem2param[map[i]][map[j]][map[k]]; + k_params.h_view(i,j,k).powerm = params[m].powerm; + k_params.h_view(i,j,k).gamma = params[m].gamma; + k_params.h_view(i,j,k).lam3 = params[m].lam3; + k_params.h_view(i,j,k).c = params[m].c; + k_params.h_view(i,j,k).d = params[m].d; + k_params.h_view(i,j,k).h = params[m].h; + k_params.h_view(i,j,k).powern = params[m].powern; + k_params.h_view(i,j,k).beta = params[m].beta; + k_params.h_view(i,j,k).lam2 = params[m].lam2; + k_params.h_view(i,j,k).bigb = params[m].bigb; + k_params.h_view(i,j,k).bigr = params[m].bigr; + k_params.h_view(i,j,k).bigd = params[m].bigd; + k_params.h_view(i,j,k).lam1 = params[m].lam1; + k_params.h_view(i,j,k).biga = params[m].biga; + k_params.h_view(i,j,k).cutsq = params[m].cutsq; + k_params.h_view(i,j,k).c1 = params[m].c1; + k_params.h_view(i,j,k).c2 = params[m].c2; + k_params.h_view(i,j,k).c3 = params[m].c3; + k_params.h_view(i,j,k).c4 = params[m].c4; + k_params.h_view(i,j,k).Z_i = params[m].Z_i; + k_params.h_view(i,j,k).Z_j = params[m].Z_j; + k_params.h_view(i,j,k).ZBLcut = params[m].ZBLcut; + k_params.h_view(i,j,k).ZBLexpscale = params[m].ZBLexpscale; } k_params.template modify(); diff --git a/src/KOKKOS/region_block_kokkos.h b/src/KOKKOS/region_block_kokkos.h index a8c9520298..19b3204973 100644 --- a/src/KOKKOS/region_block_kokkos.h +++ b/src/KOKKOS/region_block_kokkos.h @@ -33,10 +33,10 @@ template class RegBlockKokkos : public RegBlock { friend class FixPour; + public: typedef DeviceType device_type; typedef ArrayTypes AT; - public: RegBlockKokkos(class LAMMPS *, int, char **); ~RegBlockKokkos(); void match_all_kokkos(int, DAT::t_int_1d); diff --git a/src/finish.cpp b/src/finish.cpp index f305d04346..354148181e 100644 --- a/src/finish.cpp +++ b/src/finish.cpp @@ -856,7 +856,7 @@ void mpi_timings(const char *label, Timer *t, enum Timer::ttype tt, time_cpu = tmp/nprocs*100.0; // % variance from the average as measure of load imbalance - if (time > 1.0e-10) + if ((time_sq/time - time) > 1.0e-10) time_sq = sqrt(time_sq/time - time)*100.0; else time_sq = 0.0; @@ -908,7 +908,7 @@ void omp_times(FixOMP *fix, const char *label, enum Timer::ttype which, time_std /= nthreads; time_total /= nthreads; - if (time_avg > 1.0e-10) + if ((time_std/time_avg -time_avg) > 1.0e-10) time_std = sqrt(time_std/time_avg - time_avg)*100.0; else time_std = 0.0; From 770f5d0bf73663c524afa4214b068d6ea2136467 Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 12 Dec 2016 09:24:37 -0700 Subject: [PATCH 19/22] Whitespace change --- src/neighbor.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 386967cd46..14a61371ac 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1309,6 +1309,7 @@ int Neighbor::choose_stencil(NeighRequest *rq) 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 @@ -1329,6 +1330,7 @@ int Neighbor::choose_stencil(NeighRequest *rq) 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; @@ -1814,6 +1816,7 @@ void Neighbor::build_one(class NeighList *mylist, int preflag) } + // build the list np->build_setup(); From baf55c90f472347bc2d8fe3f374df27d6877047e Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 12 Dec 2016 09:25:41 -0700 Subject: [PATCH 20/22] Whitespace change --- src/neighbor.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/neighbor.cpp b/src/neighbor.cpp index 14a61371ac..d014f1c8d0 100644 --- a/src/neighbor.cpp +++ b/src/neighbor.cpp @@ -1308,8 +1308,6 @@ int Neighbor::choose_stencil(NeighRequest *rq) 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 @@ -1815,8 +1813,6 @@ void Neighbor::build_one(class NeighList *mylist, int preflag) ns->create(); } - - // build the list np->build_setup(); From 13b6196b82352dc8f3ca427e6afa6467de674d7b Mon Sep 17 00:00:00 2001 From: Stan Moore Date: Mon, 12 Dec 2016 10:47:39 -0700 Subject: [PATCH 21/22] Fixing Kokkos compile error --- src/KOKKOS/neighbor_kokkos.cpp | 26 +++++++++----------------- 1 file changed, 9 insertions(+), 17 deletions(-) diff --git a/src/KOKKOS/neighbor_kokkos.cpp b/src/KOKKOS/neighbor_kokkos.cpp index 970e3ad0f9..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 @@ -21,6 +21,11 @@ #include "atom_masks.h" #include "error.h" #include "kokkos.h" +#include "force.h" +#include "bond.h" +#include "angle.h" +#include "dihedral.h" +#include "improper.h" #include "style_nbin.h" #include "style_nstencil.h" #include "style_npair.h" @@ -74,19 +79,6 @@ void NeighborKokkos::init() atomKK = (AtomKokkos *) atom; Neighbor::init(); - - - - - - - - - - - - - // 1st time allocation of xhold if (dist_check) @@ -371,8 +363,8 @@ void NeighborKokkos::init_topology() { 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; @@ -419,4 +411,4 @@ void NeighborKokkos::build_topology_kokkos() { k_dihedrallist.modify(); k_improperlist.modify(); } -} \ No newline at end of file +} From fda43c00fd99dc2d14bf4ada441fe7677a6121bd Mon Sep 17 00:00:00 2001 From: Axel Kohlmeyer Date: Mon, 12 Dec 2016 13:22:54 -0500 Subject: [PATCH 22/22] add deleted file in package to purge list --- src/Purge.list | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Purge.list b/src/Purge.list index 496391d27c..554c5df824 100644 --- a/src/Purge.list +++ b/src/Purge.list @@ -38,6 +38,7 @@ 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