From c9c2ae6c613486bbc2b78a19df4e77691197eb32 Mon Sep 17 00:00:00 2001 From: Steve Plimpton <sjplimp@sandia.gov> Date: Wed, 7 Sep 2016 13:42:58 -0600 Subject: [PATCH] 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 | 2563 ++++++++--------- src/neighbor.h | 400 +-- src/npair.cpp | 258 ++ src/npair.h | 146 + src/npair_copy.cpp | 46 + src/{neigh_gran.h => npair_copy.h} | 31 +- 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} | 29 +- 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} | 29 +- src/ntopo_bond_partial.cpp | 92 + ...{neigh_half_bin.h => ntopo_bond_partial.h} | 29 +- 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, 23057 insertions(+), 14631 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 -------------------------------------------------------------------------- */ - -/* ---------------------------------------------------------------------- */ - -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; - } -} - -/* ---------------------------------------------------------------------- */ +// allocate space for static class variable +// prototype for non-class function -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; -} - - -/* ---------------------------------------------------------------------- - 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<int> *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; -} +NPairHalfBinNewtonSSA::NPairHalfBinNewtonSSA(LAMMPS *lmp) : NPair(lmp) {} /* ---------------------------------------------------------------------- - 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<int> *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<int> *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<int> *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<flt_t, acc_t>::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<flt_t, acc_t>::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<flt_t, acc_t>::free_nmax() template <class flt_t, class acc_t> void IntelBuffers<flt_t, acc_t>::_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<flt_t, acc_t>::_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<flt_t, acc_t>::_grow_nmax(const int offload_end) _off_map_special = special; _off_map_nspecial = nspecial; _off_map_nmax = size; - _off_map_bins = bins; #endif } /* ---------------------------------------------------------------------- */ template <class flt_t, class acc_t> -void IntelBuffers<flt_t, acc_t>::free_local() +void IntelBuffers<flt_t, acc_t>::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<flt_t, acc_t>::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 <class flt_t, class acc_t> -void IntelBuffers<flt_t, acc_t>::_grow_local(NeighList *list, - const int offload_end) +void IntelBuffers<flt_t, acc_t>::_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<flt_t, acc_t>::_grow_local(NeighList *list, /* ---------------------------------------------------------------------- */ -template <class flt_t, class acc_t> -void IntelBuffers<flt_t, acc_t>::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 <class flt_t, class acc_t> -void IntelBuffers<flt_t, acc_t>::_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 <class flt_t, class acc_t> void IntelBuffers<flt_t, acc_t>::free_nbor_list() { @@ -333,11 +283,8 @@ void IntelBuffers<flt_t, acc_t>::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<flt_t, acc_t>::_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 <class flt_t, class acc_t> -void IntelBuffers<flt_t, acc_t>::_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 <class flt_t, class acc_t> @@ -544,7 +474,6 @@ double IntelBuffers<flt_t, acc_t>::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<FixIntel *>(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 <class flt_t, class acc_t> +void NBinIntel::bin_atoms(IntelBuffers<flt_t,acc_t> * 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<flt_t>(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 <class flt_t, class acc_t> + void bin_atoms(IntelBuffers<flt_t,acc_t> *); + + #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 <omp.h> -#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 <class flt_t, class acc_t> -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<FixIntel *>(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<float,double,1>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnni<float,double,1>(0, list, fix->get_mixed_buffers(), - host_start, nlocal,fix); - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - hbnni<double,double,1>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnni<double,double,1>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } else { - hbnni<float,float,1>(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnni<float,float,1>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } else { - if (fix->precision() == FixIntel::PREC_MODE_MIXED) { - hbnni<float,double,0>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnni<float,double,0>(0, list, fix->get_mixed_buffers(), - host_start, nlocal,fix); - } else if (fix->precision() == FixIntel::PREC_MODE_DOUBLE) { - hbnni<double,double,0>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnni<double,double,0>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } else { - hbnni<float,float,0>(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnni<float,float,0>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } -} - -template <class flt_t, class acc_t, int need_ic> -void Neighbor::hbnni(const int offload, NeighList *list, void *buffers_in, - const int astart, const int aend, void *fix_in) { - IntelBuffers<flt_t,acc_t> *buffers = (IntelBuffers<flt_t,acc_t> *)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<flt_t,acc_t>(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<flt_t>(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<FixIntel *>(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<float,double,1,1>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni<float,double,1,1>(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni<float,double,0,1>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni<float,double,0,1>(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<double,double,1,1>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni<double,double,1,1>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni<double,double,0,1>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni<double,double,0,1>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni<float,float,1,1>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni<float,float,1,1>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni<float,float,0,1>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni<float,float,0,1>(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<float,double,1,0>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni<float,double,1,0>(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni<float,double,0,0>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbni<float,double,0,0>(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<double,double,1,0>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni<double,double,1,0>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni<double,double,0,0>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbni<double,double,0,0>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbni<float,float,1,0>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni<float,float,1,0>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbni<float,float,0,0>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - hbni<float,float,0,0>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } -} - -template <class flt_t, class acc_t, int offload_noghost, int need_ic> -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<flt_t,acc_t> *buffers = (IntelBuffers<flt_t,acc_t> *)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<flt_t,acc_t>(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<flt_t>(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<flt_t>::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<FixIntel *>(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<float,double,1,1>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti<float,double,1,1>(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti<float,double,0,1>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti<float,double,0,1>(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<double,double,1,1>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti<double,double,1,1>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti<double,double,0,1>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti<double,double,0,1>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti<float,float,1,1>(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti<float,float,1,1>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti<float,float,0,1>(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti<float,float,0,1>(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<float,double,1,0>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti<float,double,1,0>(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti<float,double,0,0>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - hbnti<float,double,0,0>(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<double,double,1,0>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti<double,double,1,0>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti<double,double,0,0>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - hbnti<double,double,0,0>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - hbnti<float,float,1,0>(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti<float,float,1,0>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - hbnti<float,float,0,0>(1, list, fix->get_single_buffers(), - 0, off_end, fix); - hbnti<float,float,0,0>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } -} - -template <class flt_t, class acc_t, int offload_noghost, int need_ic> -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<flt_t,acc_t> *buffers = (IntelBuffers<flt_t,acc_t> *)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<flt_t,acc_t>(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<flt_t>(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<FixIntel *>(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<float,double,1,1>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi<float,double,1,1>(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi<float,double,0,1>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi<float,double,0,1>(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<double,double,1,1>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi<double,double,1,1>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi<double,double,0,1>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi<double,double,0,1>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi<float,float,1,1>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi<float,float,1,1>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi<float,float,0,1>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi<float,float,0,1>(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<float,double,1,0>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi<float,double,1,0>(0, list, fix->get_mixed_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi<float,double,0,0>(1, list, fix->get_mixed_buffers(), - 0, off_end, fix); - fbi<float,double,0,0>(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<double,double,1,0>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi<double,double,1,0>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi<double,double,0,0>(1, list, fix->get_double_buffers(), - 0, off_end, fix); - fbi<double,double,0,0>(0, list, fix->get_double_buffers(), - host_start, nlocal, fix); - } - } else { - #ifdef _LMP_INTEL_OFFLOAD - if (offload_noghost) { - fbi<float,float,1,0>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi<float,float,1,0>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix, off_end); - } else - #endif - { - fbi<float,float,0,0>(1, list, fix->get_single_buffers(), 0, off_end, - fix); - fbi<float,float,0,0>(0, list, fix->get_single_buffers(), - host_start, nlocal, fix); - } - } - } -} - -template <class flt_t, class acc_t, int offload_noghost, int need_ic> -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<flt_t,acc_t> *buffers = (IntelBuffers<flt_t,acc_t> *)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<flt_t,acc_t>(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<flt_t>(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 <class flt_t, class acc_t> +void NPairFullBinIntel:: +fbi(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) { + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + list->inum = nlocal; + list->gnum = 0; + + int host_start = _fix->host_start_neighbor();; + const int off_end = _fix->offload_end_neighbor(); + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + int offload_noghost = _fix->offload_noghost(); + #endif + + buffers->grow_list(list, atom->nlocal, comm->nthreads, 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<flt_t,acc_t,1,1>(1, list, buffers, 0, off_end); + fbi<flt_t,acc_t,1,1>(0, list, buffers, host_start, nlocal, off_end); + } else { + fbi<flt_t,acc_t,0,1>(1, list, buffers, 0, off_end); + fbi<flt_t,acc_t,0,1>(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + fbi<flt_t,acc_t,1,0>(1, list, buffers, 0, off_end); + fbi<flt_t,acc_t,1,0>(0, list, buffers, host_start, nlocal, off_end); + } else { + fbi<flt_t,acc_t,0,0>(1, list, buffers, 0, off_end); + fbi<flt_t,acc_t,0,0>(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + fbi<flt_t,acc_t,0,1>(0, list, buffers, host_start, nlocal); + else + fbi<flt_t,acc_t,0,0>(0, list, buffers, host_start, nlocal); + #endif +} + +template <class flt_t, class acc_t, int offload_noghost, int need_ic> +void NPairFullBinIntel:: +fbi(const int offload, NeighList *list, IntelBuffers<flt_t,acc_t> *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 <class flt_t, class acc_t> + void fbi(NeighList *, IntelBuffers<flt_t,acc_t> *); + template <class flt_t, class acc_t, int, int> + void fbi(const int, NeighList *, IntelBuffers<flt_t,acc_t> *, 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 <class flt_t, class acc_t> +void NPairHalfBinNewtoffIntel:: +hbnni(NeighList *list, IntelBuffers<flt_t,acc_t> *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<flt_t,acc_t,1>(1, list, buffers, 0, off_end); + hbnni<flt_t,acc_t,1>(0, list, buffers, host_start, nlocal); + } else { + hbnni<flt_t,acc_t,0>(1, list, buffers, 0, off_end); + hbnni<flt_t,acc_t,0>(0, list, buffers, host_start, nlocal); + } + #else + if (need_ic) + hbnni<flt_t,acc_t,1>(0, list, buffers, host_start, nlocal); + else + hbnni<flt_t,acc_t,0>(0, list, buffers, host_start, nlocal); + #endif +} + +template <class flt_t, class acc_t, int need_ic> +void NPairHalfBinNewtoffIntel:: +hbnni(const int offload, NeighList *list, IntelBuffers<flt_t,acc_t> *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 <class flt_t, class acc_t> + void hbnni(NeighList *, IntelBuffers<flt_t,acc_t> *); + template <class flt_t, class acc_t, int> + void hbnni(const int, NeighList *, IntelBuffers<flt_t,acc_t> *, 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 <class flt_t, class acc_t> +void NPairHalfBinNewtonIntel:: +hbni(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) { + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + list->inum = nlocal; + + int host_start = _fix->host_start_neighbor(); + const int off_end = _fix->offload_end_neighbor(); + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + int offload_noghost = _fix->offload_noghost(); + #endif + + buffers->grow_list(list, atom->nlocal, comm->nthreads, 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<flt_t,acc_t,1,1>(1, list, buffers, 0, off_end); + hbni<flt_t,acc_t,1,1>(0, list, buffers, host_start, nlocal, off_end); + } else { + hbni<flt_t,acc_t,0,1>(1, list, buffers, 0, off_end); + hbni<flt_t,acc_t,0,1>(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + hbni<flt_t,acc_t,1,0>(1, list, buffers, 0, off_end); + hbni<flt_t,acc_t,1,0>(0, list, buffers, host_start, nlocal, off_end); + } else { + hbni<flt_t,acc_t,0,0>(1, list, buffers, 0, off_end); + hbni<flt_t,acc_t,0,0>(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + hbni<flt_t,acc_t,0,1>(0, list, buffers, host_start, nlocal); + else + hbni<flt_t,acc_t,0,0>(0, list, buffers, host_start, nlocal); + #endif +} + +template <class flt_t, class acc_t, int offload_noghost, int need_ic> +void NPairHalfBinNewtonIntel:: +hbni(const int offload, NeighList *list, IntelBuffers<flt_t,acc_t> *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<flt_t>::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 <class flt_t, class acc_t> + void hbni(NeighList *, IntelBuffers<flt_t,acc_t> *); + template <class flt_t, class acc_t, int, int> + void hbni(const int, NeighList *, IntelBuffers<flt_t,acc_t> *, 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 <class flt_t, class acc_t> +void NPairHalfBinNewtonTriIntel:: +hbnti(NeighList *list, IntelBuffers<flt_t,acc_t> *buffers) { + const int nlocal = (includegroup) ? atom->nfirst : atom->nlocal; + list->inum = nlocal; + + int host_start = _fix->host_start_neighbor(); + const int off_end = _fix->offload_end_neighbor(); + + #ifdef _LMP_INTEL_OFFLOAD + if (off_end) grow_stencil(); + if (_fix->full_host_list()) host_start = 0; + int offload_noghost = _fix->offload_noghost(); + #endif + + buffers->grow_list(list, atom->nlocal, comm->nthreads, 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<flt_t,acc_t,1,1>(1, list, buffers, 0, off_end); + hbnti<flt_t,acc_t,1,1>(0, list, buffers, host_start, nlocal, off_end); + } else { + hbnti<flt_t,acc_t,0,1>(1, list, buffers, 0, off_end); + hbnti<flt_t,acc_t,0,1>(0, list, buffers, host_start, nlocal); + } + } else { + if (offload_noghost) { + hbnti<flt_t,acc_t,1,0>(1, list, buffers, 0, off_end); + hbnti<flt_t,acc_t,1,0>(0, list, buffers, host_start, nlocal, off_end); + } else { + hbnti<flt_t,acc_t,0,0>(1, list, buffers, 0, off_end); + hbnti<flt_t,acc_t,0,0>(0, list, buffers, host_start, nlocal); + } + } + #else + if (need_ic) + hbnti<flt_t,acc_t,0,1>(0, list, buffers, host_start, nlocal); + else + hbnti<flt_t,acc_t,0,0>(0, list, buffers, host_start, nlocal); + #endif +} + +template <class flt_t, class acc_t, int offload_noghost, int need_ic> +void NPairHalfBinNewtonTriIntel:: +hbnti(const int offload, NeighList *list, IntelBuffers<flt_t,acc_t> *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 <class flt_t, class acc_t> + void hbnti(NeighList *, IntelBuffers<flt_t,acc_t> *); + template <class flt_t, class acc_t, int, int> + void hbnti(const int, NeighList *, IntelBuffers<flt_t,acc_t> *, 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<FixIntel *>(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 <omp.h> +#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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms, owned and ghost - // skip i = j - - for (j = 0; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >=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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms, owned and ghost - // skip i = j - // no molecular test when i = ghost atom - - if (i < nlocal) { - for (j = 0; j < nall; j++) { - if (i == j) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >=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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in surrounding bins in stencil including self - // skip i = j - - ibin = 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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms 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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil, including self - // 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 <string.h> -#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<int> *ipage_touch; - MyPage<double> *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<int> &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<int> &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<int> *ipage_touch; - MyPage<double> *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<int> &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<int> &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<int> &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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = 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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // when i is a ghost atom, must check if stencil bin is out of bounds - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs with owned atom only, on both procs - // stores ghost/ghost pairs only once - // no molecular test when i = ghost atom - - if (i < nlocal) { - ibin = 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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >=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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in 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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in other bins in stencil including self - // only store pair if i < j - // skip if i,j neighbor cutoff is less than bin distance - // stores own/own pairs only once - // stores own/ghost pairs on both procs - - ibin = 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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over rest of atoms in i's bin, ghosts are at end of linked list - // if j is owned atom, store it, since j is beyond i in linked list - // if j is ghost, only store if j coords are "above and to the right" of i - - for (j = bins[i]; j >= 0; j = bins[j]) { - if (j >= nlocal) { - if (x[j][2] < ztmp) continue; - if (x[j][2] == ztmp) { - if (x[j][1] < ytmp) continue; - if (x[j][1] == ytmp && x[j][0] < xtmp) continue; - } - } - - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >=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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over all atoms in 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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // only store pair if i < j - - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >=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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - // loop over owned & ghost atoms, storing neighbors - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // only store pair if i < j - // stores own/own pairs only once - // stores own/ghost pairs with owned atom only, on both procs - // stores ghost/ghost pairs only once - // no molecular test when i = ghost atom - - if (i < nlocal) { - for (j = i+1; j < nall; j++) { - if (includegroup && !(mask[j] & bitmask)) continue; - jtype = type[j]; - if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; - - delx = xtmp - x[j][0]; - dely = ytmp - x[j][1]; - delz = ztmp - x[j][2]; - rsq = delx*delx + dely*dely + delz*delz; - - if (rsq <= cutneighsq[itype][jtype]) { - if (molecular) { - if (!moltemplate) - which = find_special(special[i],nspecial[i],tag[j]); - else if (imol >=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<int> &ipage = list->ipage[tid]; - ipage.reset(); - - for (i = ifrom; i < ito; i++) { - - n = 0; - neighptr = ipage.vget(); - - itag = tag[i]; - itype = type[i]; - xtmp = x[i][0]; - ytmp = x[i][1]; - ztmp = x[i][2]; - if (moltemplate) { - imol = molindex[i]; - iatom = molatom[i]; - tagprev = tag[i] - iatom - 1; - } - - // loop over remaining atoms, owned and ghost - // 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<int> &ipage = list->ipage[tid]; - MyPage<int> &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage<int> *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<int> &ipage = list->ipage[tid]; - MyPage<int> &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage<int> *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<int> &ipage = list->ipage[tid]; - MyPage<int> &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage<int> *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<int> &ipage = list->ipage[tid]; - MyPage<int> &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage<int> *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<int> &ipage = list->ipage[tid]; - MyPage<int> &ipage_inner = listinner->ipage[tid]; - ipage.reset(); - ipage_inner.reset(); - - MyPage<int> *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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned & ghost atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms in surrounding bins in stencil including self + // skip i = j + + ibin = 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms in other bins in stencil, including self + // 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned & ghost atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms, owned and ghost + // skip i = j + // no molecular test when i = ghost atom + + if (i < nlocal) { + for (j = 0; j < nall; j++) { + if (i == j) continue; + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >=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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms, owned and ghost + // skip i = j + + for (j = 0; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + if (i == j) continue; + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >=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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms in other bins in stencil including self + // when i is a ghost atom, must check if stencil bin is out of bounds + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs with owned atom only, on both procs + // stores ghost/ghost pairs only once + // no molecular test when i = ghost atom + + if (i < nlocal) { + ibin = 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms in other bins in stencil including self + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs on both procs + + ibin = 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over rest of atoms in i's bin, ghosts are at end of linked list + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the right" of i + + for (j = bins[i]; j >= 0; j = bins[j]) { + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >=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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms in 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms in other bins in stencil including self + // only store pair if i < j + // skip if i,j neighbor cutoff is less than bin distance + // stores own/own pairs only once + // stores own/ghost pairs on both procs + + ibin = 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over rest of atoms in i's bin, ghosts are at end of linked list + // if j is owned atom, store it, since j is beyond i in linked list + // if j is ghost, only store if j coords are "above and to the right" of i + + for (j = bins[i]; j >= 0; j = bins[j]) { + if (j >= nlocal) { + if (x[j][2] < ztmp) continue; + if (x[j][2] == ztmp) { + if (x[j][1] < ytmp) continue; + if (x[j][1] == ytmp && x[j][0] < xtmp) continue; + } + } + + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >=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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over all atoms in 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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned & ghost atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over remaining atoms, owned and ghost + // only store pair if i < j + // stores own/own pairs only once + // stores own/ghost pairs with owned atom only, on both procs + // stores ghost/ghost pairs only once + // no molecular test when i = ghost atom + + if (i < nlocal) { + for (j = i+1; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >=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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + // loop over owned atoms, storing neighbors + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over remaining atoms, owned and ghost + // only store pair if i < j + + for (j = i+1; j < nall; j++) { + if (includegroup && !(mask[j] & bitmask)) continue; + jtype = type[j]; + if (exclude && exclusion(i,j,itype,jtype,mask,molecule)) continue; + + delx = xtmp - x[j][0]; + dely = ytmp - x[j][1]; + delz = ztmp - x[j][2]; + rsq = delx*delx + dely*dely + delz*delz; + + if (rsq <= cutneighsq[itype][jtype]) { + if (molecular) { + if (!moltemplate) + which = find_special(special[i],nspecial[i],tag[j]); + else if (imol >=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<int> &ipage = list->ipage[tid]; + ipage.reset(); + + for (i = ifrom; i < ito; i++) { + + n = 0; + neighptr = ipage.vget(); + + itag = tag[i]; + itype = type[i]; + xtmp = x[i][0]; + ytmp = x[i][1]; + ztmp = x[i][2]; + if (moltemplate) { + imol = molindex[i]; + iatom = molatom[i]; + tagprev = tag[i] - iatom - 1; + } + + // loop over remaining atoms, owned and ghost + // 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<int> &ipage = list->ipage[tid]; + MyPage<int> &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage<int> *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<int> &ipage = list->ipage[tid]; + MyPage<int> &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage<int> *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<int> &ipage = list->ipage[tid]; + MyPage<int> &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage<int> *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<int> &ipage = list->ipage[tid]; + MyPage<int> &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage<int> *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<int> &ipage = list->ipage[tid]; + MyPage<int> &ipage_inner = listinner->ipage[tid]; + ipage.reset(); + ipage_inner.reset(); + + MyPage<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> &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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> &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<int> &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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> &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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> &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<int> &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<int> &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 <omp.h> #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 <class flt_t, class acc_t> friend class IntelBuffers; - #endif - #endif - - friend class FixIntel; - void *fix_intel; - - template <class flt_t, class acc_t> - void bin_atoms(void *, int *, int *); - - template <class flt_t, class acc_t, int, int> - void hbni(const int, NeighList *, void *, const int, const int, void *, - const int offload_end = 0); - template <class flt_t, class acc_t, int> - void hbnni(const int, NeighList *, void *, const int, const int, void *); - template <class flt_t, class acc_t, int, int> - void hbnti(const int, NeighList *, void *, const int, const int, void *, - const int offload_end = 0); - template <class flt_t, class acc_t, int, int> - 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<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast<int> ((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<int> (bbox[0]*binsizeinv); + nbiny = static_cast<int> (bbox[1]*binsizeinv); + if (dimension == 3) nbinz = static_cast<int> (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<int> ((coord-bboxlo[0])*bininvx); + if (coord < bboxlo[0]) mbinxlo = mbinxlo - 1; + coord = bsubboxhi[0] + SMALL*bbox[0]; + mbinxhi = static_cast<int> ((coord-bboxlo[0])*bininvx); + + coord = bsubboxlo[1] - SMALL*bbox[1]; + mbinylo = static_cast<int> ((coord-bboxlo[1])*bininvy); + if (coord < bboxlo[1]) mbinylo = mbinylo - 1; + coord = bsubboxhi[1] + SMALL*bbox[1]; + mbinyhi = static_cast<int> ((coord-bboxlo[1])*bininvy); + + if (dimension == 3) { + coord = bsubboxlo[2] - SMALL*bbox[2]; + mbinzlo = static_cast<int> ((coord-bboxlo[2])*bininvz); + if (coord < bboxlo[2]) mbinzlo = mbinzlo - 1; + coord = bsubboxhi[2] + SMALL*bbox[2]; + mbinzhi = static_cast<int> ((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 <string.h> -#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<int> *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<int> *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<int> *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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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 <string.h> -#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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *ipage_touch; - MyPage<double> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int>[nmypage]; @@ -135,104 +185,56 @@ void NeighList::setup_pages(int pgsize_caller, int oneatom_caller, dpage = new MyPage<double>[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 (listgranhistory) listgranhistory->grow(nlocal,nall); + if (listinner) listinner->grow(nlocal,nall); + if (listmiddle) listmiddle->grow(nlocal,nall); - if (nmax <= maxatoms) return; - maxatoms = nmax; + // 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 (ndxAIR_ssa) memory->sfree(ndxAIR_ssa); - ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatoms, - "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"); - } - } + if (ssa) { + if (ndxAIR_ssa) memory->sfree(ndxAIR_ssa); + ndxAIR_ssa = (uint16_t (*)[8]) memory->smalloc(sizeof(uint16_t)*8*maxatom, + "neighlist:ndxAIR_ssa"); } } -/* ---------------------------------------------------------------------- - 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<int> *ipage; // pages of neighbor indices MyPage<double> *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<int> *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage<int> *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage<int> *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<int> *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage<int> *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage<int> *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<int> *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage<int> *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage<int> *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<int> *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage<int> *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage<int> *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<int> *ipage = list->ipage; - - NeighList *listinner = list->listinner; - int *ilist_inner = listinner->ilist; - int *numneigh_inner = listinner->numneigh; - int **firstneigh_inner = listinner->firstneigh; - MyPage<int> *ipage_inner = listinner->ipage; - - NeighList *listmiddle; - int *ilist_middle,*numneigh_middle,**firstneigh_middle; - MyPage<int> *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 <map> + 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,44 +98,24 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) cuttypesq = NULL; fixchecklist = NULL; - // coords at last neighboring - - maxhold = 0; - xhold = NULL; - lastcall = -1; - - // binning + // pairwise neighbor lists and associated data structs - maxhead = 0; - binhead = NULL; - maxbin = 0; - bins = NULL; - - // pair exclusion list info - - includegroup = 0; - - nex_type = maxex_type = 0; - ex1_type = ex2_type = NULL; - ex_type = NULL; + nlist = 0; + lists = NULL; - nex_group = maxex_group = 0; - ex1_group = ex2_group = ex1_bit = ex2_bit = NULL; + nbin = 0; + neigh_bin = NULL; - nex_mol = maxex_mol = 0; - ex_mol_group = ex_mol_bit = NULL; + nstencil = 0; + neigh_stencil = NULL; - // pair lists + neigh_pair = NULL; - maxatom = 0; - nblist = nglist = nslist = 0; + nstencil_perpetual = 0; + slist = NULL; - nlist = 0; - lists = NULL; - pair_build = NULL; - stencil_create = NULL; - blist = glist = slist = NULL; - anyghostlist = 0; + npair_perpetual = 0; + plist = NULL; nrequest = maxrequest = 0; requests = NULL; @@ -141,23 +127,47 @@ Neighbor::Neighbor(LAMMPS *lmp) : Pointers(lmp) 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 + 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; + last_setup_bins = -1; + + // pair exclusion list info + + includegroup = 0; + + nex_type = maxex_type = 0; + ex1_type = ex2_type = NULL; + ex_type = NULL; + + nex_group = maxex_group = 0; + ex1_group = ex2_group = ex1_bit = ex2_bit = NULL; + + nex_mol = maxex_mol = 0; + ex_mol_group = ex_mol_bit = NULL; - 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; + + 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; - memory->destroy(binhead); - memory->destroy(bins); + 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<Class>; \ + 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<Class>; \ + 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<Class>; \ + 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) { - - // 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]; + if (same) return; + + // delete old lists and create new ones - // initialize to NULL since some may be Kokkos lists + 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; - 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; } - - // create individual lists, one per request - // pass list ptr back to requestor (except for Command class) - // wait to allocate initial pages until copy lists are detected - - for (i = 0; i < nrequest; i++) { - if (requests[i]->kokkos_host || requests[i]->kokkos_device) continue; - 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]); - } + 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]); } + } - // 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; + // morph requests via A,B,C rules + // this is to avoid duplicate or inefficient builds + // update both request and list when morph - // respaouter: point this list at preceeding 1/2 inner/middle lists + // (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 - } 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; + 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 (processed) continue; - - // pair and half and newton != 2: - // if there is a full non-occasional non-skip list - // change this list to half_from_full and point at the full list - // parent could be copy list or pair or fix - // could remove newton != 2 check if added half_from_full_no_newton_ghost - // option in neigh_derive.cpp and below in choose_build() - // this would require full list had ghost info - // would be useful when reax/c used in hybrid mode, e.g. with airebo - - if (requests[i]->pair && requests[i]->half && requests[i]->newton != 2) { - for (j = 0; j < nrequest; j++) { - if (!lists[j]) continue; - if (requests[j]->full && requests[j]->occasional == 0 && - requests[j]->skip == 0) break; - } - if (j < nrequest) { - requests[i]->half = 0; - requests[i]->half_from_full = 1; - lists[i]->listfull = lists[j]; - } - - // fix/compute requests: - // whether request is occasional or not doesn't matter - // if request = half and non-skip pair half/respaouter exists, - // if request = full and non-skip pair full exists, - // if request = half and non-skip pair full exists, - // if no matches, do nothing - // fix/compute list will be built independently as needed - // ok if parent is itself a copy list - - } else if (requests[i]->fix || requests[i]->compute) { - for (j = 0; j < nrequest; j++) { - if (!lists[j]) continue; - if (requests[i]->half && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->half) break; - if (requests[i]->full && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->full) break; - if (requests[i]->gran && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->gran) break; - if (requests[i]->half && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->respaouter) break; - } - if (j < nrequest) { - requests[i]->copy = 1; - requests[i]->otherlist = j; - lists[i]->listcopy = lists[j]; - } else { - for (j = 0; j < nrequest; j++) { - if (!lists[j]) continue; - if (requests[i]->half && requests[j]->pair && - requests[j]->skip == 0 && requests[j]->full) break; - } - if (j < nrequest) { - requests[i]->half = 0; - requests[i]->half_from_full = 1; - lists[i]->listfull = lists[j]; - } - } + if (j < nrequest) { + requests[i]->half = 0; + requests[i]->half_from_full = 1; + lists[i]->listfull = lists[j]; } } - - // 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); - } + } + + // (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; } - - if (dnummax) { - delete [] zeroes; - zeroes = new double[dnummax]; - for (i = 0; i < dnummax; i++) zeroes[i] = 0.0; + if (j < nrequest) { + requests[i]->copy = 1; + requests[i]->otherlist = j; + lists[i]->copy = 1; + lists[i]->listcopy = lists[j]; + continue; } - - // 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; + 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 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 - - anyghostlist = 0; - int anybuild = 0; - - 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; - - lists[i]->growflag = 1; - if (requests[i]->copy) lists[i]->growflag = 0; - - lists[i]->stencilflag = 1; - if (style == NSQ) lists[i]->stencilflag = 0; - if (stencil_create[i] == NULL) lists[i]->stencilflag = 0; - - 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); + if (j < nrequest) { + requests[i]->half = 0; + requests[i]->half_from_full = 1; + lists[i]->listfull = lists[j]; } + } + + // 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"); + + flag = choose_stencil(requests[i]); + lists[i]->stencil_method = flag; + if (flag < 0) + error->all(FLERR,"Requested neighbor stencil method does not exist"); + + flag = choose_pair(requests[i]); + lists[i]->pair_method = flag; + if (flag < 0) + error->all(FLERR,"Requested neighbor pair method does not exist"); + } - // no request has the buildflag set, so set it for the first request only - // this insure binning is done for any occasional neighbor lists + // instantiate unique Bin,Stencil classes in neigh_bin & neigh_stencil vecs + // instantiate one Pair class per list in neigh_pair vec + + 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++; + } - if (!anybuild) { - for (i = 0; i < nrequest; i++) { - if (lists[i]) { - lists[i]->buildflag = 1; - break; - } + 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; } } + if (k == nbin) + error->all(FLERR,"Could not assign bin method to neighbor stencil"); + nstencil++; + } -#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); + 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; - // 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); + 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 (k == nbin) + error->all(FLERR,"Could not assign bin method to neighbor pair"); } - - // 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; + 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; } - -#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; - break; } + if (k == nstencil) + error->all(FLERR,"Could not assign stencil method to neighbor pair"); } + } -#ifdef NEIGH_LIST_DEBUG - print_lists_of_lists(); -#endif + // 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; } - // output neighbor list info, only first time or when info changes - - 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)); - } - 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)); - } + // 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); } } - // 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; + // 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); } - - if (atom->molecular && atom->nbonds && maxbond == 0) { - if (nprocs == 1) maxbond = atom->nbonds; - else maxbond = static_cast<int> (LB_FACTOR * atom->nbonds / nprocs); - memory->create(bondlist,maxbond,3,"neigh:bondlist"); + + for (i = 0; i < nstencil; i++) { + flag = 0; + for (j = 0; j < npair_perpetual; j++) + if (lists[plist[j]]->stencil_method == neigh_stencil[i]->istyle) flag = 1; + if (flag) slist[nstencil_perpetual++] = i; } - if (atom->molecular && atom->nangles && maxangle == 0) { - if (nprocs == 1) maxangle = atom->nangles; - else maxangle = static_cast<int> (LB_FACTOR * atom->nangles / nprocs); - memory->create(anglelist,maxangle,4,"neigh:anglelist"); + // reorder plist vector if necessary + // relevant for lists that copy/skip/half-full from parent + // the child index must appear in plist after the parent index + // swap two indices within plist when dependency is mis-ordered + // done when entire pass thru plist results in no swaps + + NeighList *ptr; + + int done = 0; + while (!done) { + done = 1; + for (i = 0; i < npair_perpetual; i++) { + 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->ndihedrals && maxdihedral == 0) { - if (nprocs == 1) maxdihedral = atom->ndihedrals; - else maxdihedral = static_cast<int> - (LB_FACTOR * atom->ndihedrals / nprocs); - memory->create(dihedrallist,maxdihedral,5,"neigh:dihedrallist"); - } + // debug output - if (atom->molecular && atom->nimpropers && maximproper == 0) { - if (nprocs == 1) maximproper = atom->nimpropers; - else maximproper = static_cast<int> - (LB_FACTOR * atom->nimpropers / nprocs); - memory->create(improperlist,maximproper,5,"neigh:improperlist"); - } +#ifdef NEIGH_LIST_DEBUG + for (i = 0; i < nrequest; i++) lists[i]->print_attributes(); +#endif +} + +/* ---------------------------------------------------------------------- + create and initialize NTopo classes +------------------------------------------------------------------------- */ + +void Neighbor::init_topology() +{ + int i,m; - // set flags that determine which topology neighboring routines to use + 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,502 +1002,560 @@ 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); - - // set ptrs to topology build functions + 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); + + // instantiate NTopo classes + + 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) bond_build = &Neighbor::bond_template; - else if (bond_off) bond_build = &Neighbor::bond_partial; - else bond_build = &Neighbor::bond_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) angle_build = &Neighbor::angle_template; - else if (angle_off) angle_build = &Neighbor::angle_partial; - else angle_build = &Neighbor::angle_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) dihedral_build = &Neighbor::dihedral_template; - else if (dihedral_off) dihedral_build = &Neighbor::dihedral_partial; - else dihedral_build = &Neighbor::dihedral_all; + 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); + } + } +} - if (atom->molecular == 2) improper_build = &Neighbor::improper_template; - else if (improper_off) improper_build = &Neighbor::improper_partial; - else improper_build = &Neighbor::improper_all; +/* ---------------------------------------------------------------------- + output summary of pairwise neighbor list info + only called by proc 0 +------------------------------------------------------------------------- */ - // set topology neighbor list counts to 0 - // in case all are turned off but potential is still defined +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++; + } - nbondlist = nanglelist = ndihedrallist = nimproperlist = 0; + 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); -int Neighbor::request(void *requestor, int instance) + 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) { - if (nrequest == maxrequest) { - maxrequest += RQDELTA; - requests = (NeighRequest **) - memory->srealloc(requests,maxrequest*sizeof(NeighRequest *), - "neighbor:requests"); + // 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; } - requests[nrequest] = new NeighRequest(lmp); - requests[nrequest]->requestor = requestor; - requests[nrequest]->requestor_instance = instance; - nrequest++; - return nrequest-1; + // error return if matched none + + return -1; } /* ---------------------------------------------------------------------- - 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 + 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 ------------------------------------------------------------------------- */ -void Neighbor::choose_build(int index, NeighRequest *rq) +int Neighbor::choose_stencil(NeighRequest *rq) { - 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; - } + // no stencil creation needed - } 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; - } + 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; - } 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; - } + // 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 - } 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"); - } + int halfflag,fullflag,ghostflag,ssaflag; - // OMP versions of build methods + halfflag = fullflag = ghostflag = ssaflag = 0; - } else { + if (rq->half) halfflag = 1; + if (rq->full) fullflag = 1; + if (rq->gran) halfflag = 1; + if (rq->respaouter) halfflag = 1; - 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; - } + if (rq->ghost) ghostflag = NS_GHOST; + if (rq->ssa) ssaflag = NS_SSA; - } 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; - } + 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]; - } 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"); + 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; } - pair_build[index] = pb; + // error return if matched none + + return -1; } /* ---------------------------------------------------------------------- - 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 + 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 ------------------------------------------------------------------------- */ -void Neighbor::choose_stencil(int index, NeighRequest *rq) +int Neighbor::choose_pair(NeighRequest *rq) { - 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; - } - } + // 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; + } - } 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; - } + 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; } - } 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; - } + 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; } - stencil_create[index] = sc; + //printf("NO MATCH\n"); + + // error return if matched none + + return -1; } -/* ---------------------------------------------------------------------- */ +/* ---------------------------------------------------------------------- + called by other classes to request a pairwise neighbor list +------------------------------------------------------------------------- */ -void Neighbor::print_lists_of_lists() +int Neighbor::request(void *requestor, int instance) { - 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"); + if (nrequest == maxrequest) { + maxrequest += RQDELTA; + requests = (NeighRequest **) + memory->srealloc(requests,maxrequest*sizeof(NeighRequest *), + "neighbor:requests"); } + + requests[nrequest] = new NeighRequest(lmp); + requests[nrequest]->index = nrequest; + requests[nrequest]->requestor = requestor; + requests[nrequest]->requestor_instance = instance; + nrequest++; + return nrequest-1; +} + +/* ---------------------------------------------------------------------- + one instance per entry in style_neigh_bin.h +------------------------------------------------------------------------- */ + +template <typename T> +NBin *Neighbor::bin_creator(LAMMPS *lmp) +{ + return new T(lmp); +} + +/* ---------------------------------------------------------------------- + one instance per entry in style_neigh_stencil.h +------------------------------------------------------------------------- */ + +template <typename T> +NStencil *Neighbor::stencil_creator(LAMMPS *lmp) +{ + return new T(lmp); +} + +/* ---------------------------------------------------------------------- + one instance per entry in style_neigh_pair.h +------------------------------------------------------------------------- */ + +template <typename T> +NPair *Neighbor::pair_creator(LAMMPS *lmp) +{ + 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) - - 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); - } - - // extend atom bin list if necessary + // 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 (style != NSQ && atom->nmax > maxbin) { - maxbin = atom->nmax; - memory->destroy(bins); - memory->create(bins,maxbin,"bins"); + if (style != NSQ) { + for (int i = 0; i < nbin; i++) { + neigh_bin[i]->bin_atoms_setup(nall); + neigh_bin[i]->bin_atoms(); + } } - // check that using special bond flags will not overflow neigh lists + // build pairwise lists for all perpetual NPair/NeighList + // grow() with nlocal/nall args so that only realloc if have to - 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 < npair_perpetual; i++) { + m = plist[i]; + lists[m]->grow(nlocal,nall); + neigh_pair[m]->build_setup(); + neigh_pair[m]->build(lists[m]); + } - 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->stencilflag) { - mylist->stencil_allocate(smax,style); - (this->*stencil_create[mylist->index])(mylist,sx,sy,sz); - } + if (mylist->listcopy && mylist->listcopy->occasional) + build_one(mylist->listcopy,preflag); + if (mylist->listfull && mylist->listfull->occasional) + build_one(mylist->listfull,preflag); - if (mylist->growflag) mylist->grow(maxatom); + // create stencil if hasn't been created since last setup_bins() call - // 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<int> (bbox[0]*binsizeinv); - nbiny = static_cast<int> (bbox[1]*binsizeinv); - if (dimension == 3) nbinz = static_cast<int> (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<int> ((coord-bboxlo[0])*bininvx); - if (coord < bboxlo[0]) mbinxlo = mbinxlo - 1; - coord = bsubboxhi[0] + SMALL*bbox[0]; - mbinxhi = static_cast<int> ((coord-bboxlo[0])*bininvx); - - coord = bsubboxlo[1] - SMALL*bbox[1]; - mbinylo = static_cast<int> ((coord-bboxlo[1])*bininvy); - if (coord < bboxlo[1]) mbinylo = mbinylo - 1; - coord = bsubboxhi[1] + SMALL*bbox[1]; - mbinyhi = static_cast<int> ((coord-bboxlo[1])*bininvy); - - if (dimension == 3) { - coord = bsubboxlo[2] - SMALL*bbox[2]; - mbinzlo = static_cast<int> ((coord-bboxlo[2])*bininvz); - if (coord < bboxlo[2]) mbinzlo = mbinzlo - 1; - coord = bsubboxhi[2] + SMALL*bbox[2]; - mbinzhi = static_cast<int> ((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 + NStencil *ns = np->ns; + if (ns && ns->last_create < last_setup_bins) { + ns->create_setup(); + ns->create(); } - // 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<int> (cutneighmax*bininvx); - if (sx*binsizex < cutneighmax) sx++; - sy = static_cast<int> (cutneighmax*bininvy); - if (sy*binsizey < cutneighmax) sy++; - sz = static_cast<int> (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; + // build the list - 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<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; - else if (x[0] >= bboxlo[0]) { - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); - ix = MIN(ix,nbinx-1); - } else - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; - else if (x[1] >= bboxlo[1]) { - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); - iy = MIN(iy,nbiny-1); - } else - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; - else if (x[2] >= bboxlo[2]) { - iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); - iz = MIN(iz,nbinz-1); - } else - iz = static_cast<int> ((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<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; - else if (x[0] >= bboxlo[0]) { - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); - ix = MIN(ix,nbinx-1); - } else - ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; - - if (x[1] >= bboxhi[1]) - iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; - else if (x[1] >= bboxlo[1]) { - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); - iy = MIN(iy,nbiny-1); - } else - iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; - - if (x[2] >= bboxhi[2]) - iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; - else if (x[2] >= bboxlo[2]) { - iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); - iz = MIN(iz,nbinz-1); - } else - iz = static_cast<int> ((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,6 +1997,16 @@ void Neighbor::exclusion_group_group_delete(int group1, int group2) nex_group--; } + +/* ---------------------------------------------------------------------- + return the value of exclude - used to check compatibility with GPU +------------------------------------------------------------------------- */ + +int Neighbor::exclude_setting() +{ + return exclude; +} + /* ---------------------------------------------------------------------- return # of bytes of allocated memory ------------------------------------------------------------------------- */ @@ -2249,27 +2016,17 @@ 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++) + 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(); - bytes += memory->usage(bondlist,maxbond,3); - bytes += memory->usage(anglelist,maxangle,4); - bytes += memory->usage(dihedrallist,maxdihedral,5); - bytes += memory->usage(improperlist,maximproper,5); + 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; } - -/* ---------------------------------------------------------------------- - return the value of exclude - used to check compatibility with GPU -------------------------------------------------------------------------- */ - -int Neighbor::exclude_setting() -{ - return exclude; -} 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 <map> 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 + double (*corners)[3]; // ptr to 8 corners of triclinic box - 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 inner[2],middle[2]; // rRESPA cutoffs for extra lists - double binsizex,binsizey,binsizez; // actual bin sizes and inverse sizes - double bininvx,bininvy,bininvz; + 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 sx,sy,sz,smax; // bin stencil extents + 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 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 + int maxex_type; // max # in exclusion type list + int maxex_group; // max # in exclusion group list + int maxex_mol; // max # in exclusion molecule list - 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 maxatom; // size of atom-based NeighList arrays + int maxrequest; // size of NeighRequest list + int maxwt; // max weighting factor applied + 1 - int special_flag[4]; // flags for 1-2, 1-3, 1-4 neighbors + // info for other Neigh classes: NBin,NStencil,NPair,NTopo - int anyghostlist; // 1 if any non-occasional list - // stores neighbors of ghosts + int nbin,nstencil; + int nbclass,nsclass,npclass; + int bondwhich,anglewhich,dihedralwhich,improperwhich; - int exclude; // 0 if no type/group exclusions, 1 if yes + typedef class NBin *(*BinCreator)(class LAMMPS *); + BinCreator *binclass; + char **binnames; + int *binmasks; + class NBin **neigh_bin; - 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 + typedef class NStencil *(*StencilCreator)(class LAMMPS *); + StencilCreator *stencilclass; + char **stencilnames; + int *stencilmasks; + class NStencil **neigh_stencil; - 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 + typedef class NPair *(*PairCreator)(class LAMMPS *); + PairCreator *pairclass; + char **pairnames; + int *pairmasks; + class NPair **neigh_pair; - 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 + class NTopo *neigh_bond; + class NTopo *neigh_angle; + class NTopo *neigh_dihedral; + class NTopo *neigh_improper; - 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 + // internal methods + // including creator methods for Nbin,Nstencil,Npair instances - double *zeroes; // vector of zeroes for shear history init + void init_styles(); + void init_pair(); + void init_topology(); - // methods + void print_pairwise_info(); + void requests_new2old(); - 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 + int choose_bin(class NeighRequest *); + int choose_stencil(class NeighRequest *); + int choose_pair(class NeighRequest *); - int exclusion(int, int, int, - int, int *, tagint *) const; // test for pair exclusion + template <typename T> static NBin *bin_creator(class LAMMPS *); + template <typename T> static NStencil *stencil_creator(class LAMMPS *); + template <typename T> static NPair *pair_creator(class LAMMPS *); - virtual void choose_build(int, class NeighRequest *); - void choose_stencil(int, class NeighRequest *); + // dummy functions provided by NeighborKokkos, called in init() + // otherwise NeighborKokkos would have to overwrite init() - // dummy functions provided by NeighborKokkos + 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 <math.h> +#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<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast<int> ((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<int> ((x[0]-bboxhi[0])*bininvx) + nbinx; + else if (x[0] >= bboxlo[0]) { + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx); + ix = MIN(ix,nbinx-1); + } else + ix = static_cast<int> ((x[0]-bboxlo[0])*bininvx) - 1; + + if (x[1] >= bboxhi[1]) + iy = static_cast<int> ((x[1]-bboxhi[1])*bininvy) + nbiny; + else if (x[1] >= bboxlo[1]) { + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy); + iy = MIN(iy,nbiny-1); + } else + iy = static_cast<int> ((x[1]-bboxlo[1])*bininvy) - 1; + + if (x[2] >= bboxhi[2]) + iz = static_cast<int> ((x[2]-bboxhi[2])*bininvz) + nbinz; + else if (x[2] >= bboxlo[2]) { + iz = static_cast<int> ((x[2]-bboxlo[2])*bininvz); + iz = MIN(iz,nbinz-1); + } else + iz = static_cast<int> ((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. ------------------------------------------------------------------------- */ -/* ERROR/WARNING messages: +#ifdef NPAIR_CLASS + +NPairStyle(copy, + NPairCopy, + NP_COPY) + +#else + +#ifndef LMP_NPAIR_COPY_H +#define LMP_NPAIR_COPY_H + +#include "npair.h" -E: Neighbor list overflow, boost neigh_modify one +namespace LAMMPS_NS { -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. +class NPairCopy : public NPair { + public: + NPairCopy(class LAMMPS *); + ~NPairCopy() {} + void build(class NeighList *); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: */ 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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage<int> *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage<int> *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<int> *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage<int> *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage<int> *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<int> *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage<int> *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage<int> *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<int> *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage<int> *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage<int> *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<int> *ipage = list->ipage; + + NeighList *listinner = list->listinner; + int *ilist_inner = listinner->ilist; + int *numneigh_inner = listinner->numneigh; + int **firstneigh_inner = listinner->firstneigh; + MyPage<int> *ipage_inner = listinner->ipage; + + NeighList *listmiddle; + int *ilist_middle,*numneigh_middle,**firstneigh_middle; + MyPage<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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 <string.h> +#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<int> *ipage_touch; + MyPage<double> *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<int> *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<int> (cutneighmax*bininvx); + if (sx*binsizex < cutneighmax) sx++; + sy = static_cast<int> (cutneighmax*bininvy); + if (sy*binsizey < cutneighmax) sy++; + sz = static_cast<int> (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 <math.h> +#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<int> (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<int> (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<int> (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<int> (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 <mpi.h> +#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. ------------------------------------------------------------------------- */ -/* ERROR/WARNING messages: +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_ANGLE_ALL,NTopoAngleAll) + +#else + +#ifndef LMP_TOPO_ANGLE_ALL_H +#define LMP_TOPO_ANGLE_ALL_H + +#include "ntopo.h" -E: Neighbor list overflow, boost neigh_modify one +namespace LAMMPS_NS { -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. +class NTopoAngleAll : public NTopo { + public: + NTopoAngleAll(class LAMMPS *); + ~NTopoAngleAll() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: */ 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 <mpi.h> +#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 <mpi.h> +#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 <mpi.h> +#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. ------------------------------------------------------------------------- */ -/* ERROR/WARNING messages: +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_BOND_ALL,NTopoBondAll) + +#else + +#ifndef LMP_TOPO_BOND_ALL_H +#define LMP_TOPO_BOND_ALL_H + +#include "ntopo.h" -E: Neighbor list overflow, boost neigh_modify one +namespace LAMMPS_NS { -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. +class NTopoBondAll : public NTopo { + public: + NTopoBondAll(class LAMMPS *); + ~NTopoBondAll() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: */ 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 <mpi.h> +#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. ------------------------------------------------------------------------- */ -/* ERROR/WARNING messages: +#ifdef NTOPO_CLASS + +NTopoStyle(NTOPO_BOND_PARTIAL,NTopoBondPartial) + +#else + +#ifndef LMP_TOPO_BOND_PARTIAL_H +#define LMP_TOPO_BOND_PARTIAL_H + +#include "ntopo.h" -E: Neighbor list overflow, boost neigh_modify one +namespace LAMMPS_NS { -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. +class NTopoBondPartial : public NTopo { + public: + NTopoBondPartial(class LAMMPS *); + ~NTopoBondPartial() {} + void build(); +}; + +} + +#endif +#endif + +/* ERROR/WARNING messages: */ diff --git a/src/ntopo_bond_template.cpp b/src/ntopo_bond_template.cpp new file mode 100644 index 0000000000..de16d78585 --- /dev/null +++ b/src/ntopo_bond_template.cpp @@ -0,0 +1,109 @@ +/* ---------------------------------------------------------------------- + LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator + http://lammps.sandia.gov, Sandia National Laboratories + Steve Plimpton, sjplimp@sandia.gov + + Copyright (2003) Sandia Corporation. Under the terms of Contract + DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains + certain rights in this software. This software is distributed under + the GNU General Public License. + + See the README file in the top-level LAMMPS directory. +------------------------------------------------------------------------- */ + +#include <mpi.h> +#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 <mpi.h> +#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 <mpi.h> +#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 <mpi.h> +#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 <mpi.h> +#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 <mpi.h> +#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 <mpi.h> +#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: + +*/ -- GitLab