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