From 66c5617afbe6108d53efa3e51278de71500b857b Mon Sep 17 00:00:00 2001
From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa>
Date: Mon, 25 Jun 2012 22:03:31 +0000
Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@8395
 f3b2605a-c512-4ea7-a41b-209d697bcdaa

---
 src/DIPOLE/atom_vec_dipole.cpp         |    9 +-
 src/DIPOLE/atom_vec_dipole.h           |    5 +-
 src/MAKE/Makefile.serial               |    5 +-
 src/MANYBODY/Install.sh                |    4 +
 src/MANYBODY/pair_bop.cpp              | 9896 ++++++++++++++++++++++++
 src/MANYBODY/pair_bop.h                |  216 +
 src/MOLECULE/atom_vec_angle.cpp        |    9 +-
 src/MOLECULE/atom_vec_angle.h          |    5 +-
 src/MOLECULE/atom_vec_bond.cpp         |    9 +-
 src/MOLECULE/atom_vec_bond.h           |    5 +-
 src/MOLECULE/atom_vec_full.cpp         |    9 +-
 src/MOLECULE/atom_vec_full.h           |    5 +-
 src/MOLECULE/atom_vec_molecular.cpp    |    9 +-
 src/MOLECULE/atom_vec_molecular.h      |    5 +-
 src/PERI/atom_vec_peri.cpp             |    9 +-
 src/PERI/atom_vec_peri.h               |    5 +-
 src/POEMS/fix_poems.cpp                |   58 +-
 src/REPLICA/compute_event_displace.cpp |   14 +-
 src/REPLICA/fix_event.cpp              |   13 +-
 src/REPLICA/tad.cpp                    |    9 +-
 src/USER-AWPMD/atom_vec_wavepacket.cpp |    9 +-
 src/USER-AWPMD/atom_vec_wavepacket.h   |    5 +-
 src/USER-EFF/atom_vec_electron.cpp     |    9 +-
 src/USER-EFF/atom_vec_electron.h       |    5 +-
 src/USER-MISC/compute_temp_rotate.cpp  |   16 +-
 src/USER-MISC/fix_addtorque.cpp        |   14 +-
 src/USER-MISC/fix_imd.cpp              |   14 +-
 src/USER-MOLFILE/dump_molfile.cpp      |    8 +-
 src/USER-SPH/atom_vec_meso.cpp         |    9 +-
 src/USER-SPH/atom_vec_meso.h           |    5 +-
 src/XTC/dump_xtc.cpp                   |   10 +-
 src/atom.cpp                           |   20 +-
 src/atom.h                             |    3 +-
 src/atom_vec.h                         |    2 +-
 src/atom_vec_atomic.cpp                |  135 +-
 src/atom_vec_atomic.h                  |    5 +-
 src/atom_vec_charge.cpp                |    9 +-
 src/atom_vec_charge.h                  |    5 +-
 src/atom_vec_ellipsoid.cpp             |    9 +-
 src/atom_vec_ellipsoid.h               |    5 +-
 src/atom_vec_hybrid.cpp                |    2 +-
 src/atom_vec_hybrid.h                  |    5 +-
 src/atom_vec_line.cpp                  |    9 +-
 src/atom_vec_line.h                    |    5 +-
 src/atom_vec_sphere.cpp                |    9 +-
 src/atom_vec_sphere.h                  |    5 +-
 src/atom_vec_tri.cpp                   |    9 +-
 src/atom_vec_tri.h                     |    5 +-
 src/change_box.cpp                     |    2 +-
 src/compute_com_molecule.cpp           |    8 +-
 src/compute_displace_atom.cpp          |   14 +-
 src/compute_gyration.cpp               |    8 +-
 src/compute_gyration_molecule.cpp      |   24 +-
 src/compute_msd.cpp                    |   14 +-
 src/compute_msd_molecule.cpp           |    8 +-
 src/compute_property_atom.cpp          |   42 +-
 src/create_atoms.cpp                   |    3 +-
 src/displace_atoms.cpp                 |    2 +-
 src/domain.cpp                         |  121 +-
 src/domain.h                           |    6 +-
 src/dump_atom.cpp                      |   24 +-
 src/dump_custom.cpp                    |  132 +-
 src/dump_dcd.cpp                       |    8 +-
 src/fix_addforce.cpp                   |    8 +-
 src/fix_deform.cpp                     |    2 +-
 src/fix_momentum.cpp                   |    8 +-
 src/fix_move.cpp                       |    4 +-
 src/fix_nh.cpp                         |    2 +-
 src/fix_orient_fcc.cpp                 |    6 +-
 src/fix_rigid.cpp                      |  100 +-
 src/fix_rigid.h                        |    2 +-
 src/fix_rigid_nve.cpp                  |    8 +-
 src/fix_rigid_nvt.cpp                  |    8 +-
 src/fix_spring_rg.cpp                  |    8 +-
 src/fix_spring_self.cpp                |   16 +-
 src/fix_store_state.cpp                |   42 +-
 src/fix_tmd.cpp                        |   28 +-
 src/group.cpp                          |   92 +-
 src/lmptype.h                          |   20 +-
 src/read_dump.cpp                      |   20 +-
 src/replicate.cpp                      |    6 +-
 src/set.cpp                            |   11 +-
 src/velocity.cpp                       |    8 +-
 83 files changed, 10821 insertions(+), 639 deletions(-)
 create mode 100644 src/MANYBODY/pair_bop.cpp
 create mode 100644 src/MANYBODY/pair_bop.h

diff --git a/src/DIPOLE/atom_vec_dipole.cpp b/src/DIPOLE/atom_vec_dipole.cpp
index 02f048e3d8..85fea0735b 100644
--- a/src/DIPOLE/atom_vec_dipole.cpp
+++ b/src/DIPOLE/atom_vec_dipole.cpp
@@ -609,7 +609,7 @@ int AtomVecDipole::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   q[nlocal] = buf[m++];
   mu[nlocal][0] = buf[m++];
@@ -700,7 +700,7 @@ int AtomVecDipole::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -737,7 +737,8 @@ void AtomVecDipole::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -756,7 +757,7 @@ void AtomVecDipole::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecDipole::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecDipole::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/DIPOLE/atom_vec_dipole.h b/src/DIPOLE/atom_vec_dipole.h
index 52b751f10d..bdbf180a8e 100644
--- a/src/DIPOLE/atom_vec_dipole.h
+++ b/src/DIPOLE/atom_vec_dipole.h
@@ -50,12 +50,13 @@ class AtomVecDipole : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double *q,**mu,**omega,**torque;
 };
diff --git a/src/MAKE/Makefile.serial b/src/MAKE/Makefile.serial
index 8849b18432..2d9d9227a6 100755
--- a/src/MAKE/Makefile.serial
+++ b/src/MAKE/Makefile.serial
@@ -4,8 +4,7 @@ SHELL = /bin/sh
 
 # ---------------------------------------------------------------------
 # compiler/linker settings
-# generally no need to edit this section
-# unless additional compiler/linker flags or libraries needed for your machine
+# specify flags and libraries needed for your compiler
 
 CC =		g++
 CCFLAGS =	-O
@@ -25,7 +24,7 @@ SIZE =		size
 # LAMMPS ifdef settings, OPTIONAL
 # see possible settings in doc/Section_start.html#2_2 (step 4)
 
-LMP_INC =	-DLAMMPS_GZIP
+LMP_INC =	-DLAMMPS_GZIP -DLAMMPS_BIGBIG
 
 # MPI library, REQUIRED
 # see discussion in doc/Section_start.html#2_2 (step 5)
diff --git a/src/MANYBODY/Install.sh b/src/MANYBODY/Install.sh
index 8d36e8e9de..de0181af2f 100644
--- a/src/MANYBODY/Install.sh
+++ b/src/MANYBODY/Install.sh
@@ -5,6 +5,7 @@ if (test $1 = 1) then
   cp fix_qeq_comb.cpp ..
   cp pair_adp.cpp ..
   cp pair_airebo.cpp ..
+  cp pair_bop.cpp ..
   cp pair_comb.cpp ..
   cp pair_eam.cpp ..
   cp pair_eam_alloy.cpp ..
@@ -19,6 +20,7 @@ if (test $1 = 1) then
   cp fix_qeq_comb.h ..
   cp pair_adp.h ..
   cp pair_airebo.h ..
+  cp pair_bop.h ..
   cp pair_comb.h ..
   cp pair_eam.h ..
   cp pair_eam_alloy.h ..
@@ -35,6 +37,7 @@ elif (test $1 = 0) then
   rm -f ../fix_qeq_comb.cpp
   rm -f ../pair_adp.cpp
   rm -f ../pair_airebo.cpp
+  rm -f ../pair_bop.cpp
   rm -f ../pair_comb.cpp
   rm -f ../pair_eam.cpp
   rm -f ../pair_eam_alloy.cpp
@@ -49,6 +52,7 @@ elif (test $1 = 0) then
   rm -f ../fix_qeq_comb.h
   rm -f ../pair_adp.h
   rm -f ../pair_airebo.h
+  rm -f ../pair_bop.h
   rm -f ../pair_comb.h
   rm -f ../pair_eam.h
   rm -f ../pair_eam_alloy.h
diff --git a/src/MANYBODY/pair_bop.cpp b/src/MANYBODY/pair_bop.cpp
new file mode 100644
index 0000000000..7289e6b1fd
--- /dev/null
+++ b/src/MANYBODY/pair_bop.cpp
@@ -0,0 +1,9896 @@
+/* ----------------------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   Copyright (2003) Sandia Corporation.  Under the terms of Contract
+   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+   certain 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: D.K. Ward (donward@sandia.gov) and X.W. Zhou (Sandia)
+------------------------------------------------------------------------- */
+
+/* ----------------------------------------------------------------------
+   The formulation for this work follows (a) D.G. Pettifor, et al., Mat.
+   Sci. and Eng. A365, 2-13, (2004);(b) D.A. Murdick, et al., Phys.
+   Rev. B 73, 045206 (2006);(c) D.G. Pettifor and I.I. Oleinik., Phys
+   Rev. Lett. 84, 4124 (2000); (d) D.K. Ward, et al., Phys. Rev. B 85, 
+   115206 (2012).
+
+   Copyright (2012) Sandia Corporation.  Under the terms of Contract DE-
+   AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+   rights in this software.
+
+   pairbop v 1.0 comes with no warranty of any kind.  pairbop v 1.0 is a
+   copyrighted code that is distributed free-of-charge, under the terms
+   of the GNU Public License (GPL).  See "Open-Source
+   Rules"_http://lammps.sandia.gov/open_source.html
+------------------------------------------------------------------------- */
+
+#include "math.h"
+#include "stdio.h"
+#include "stdlib.h"
+#include "string.h"
+#include "mpi.h"
+#include "pair_bop.h"
+#include "atom.h"
+#include "neighbor.h"
+#include "neigh_request.h"
+#include "force.h"
+#include "timer.h"
+#include "comm.h"
+#include "neighbor.h"
+#include "neigh_list.h"
+#include "neigh_request.h"
+#include "memory.h"
+#include "error.h"
+#include "domain.h"
+
+using namespace LAMMPS_NS;
+
+#define MAXLINE 1024
+
+/* ---------------------------------------------------------------------- */
+
+PairBOP::PairBOP(LAMMPS *lmp) : Pair(lmp)
+{
+  single_enable = 0;
+  one_coeff = 1;
+  map = NULL;
+  pi_a = NULL;
+  pro_delta = NULL;
+  pi_delta = NULL;
+  pi_p = NULL;
+  pi_c = NULL;
+  sigma_r0 = NULL;
+  pi_r0 = NULL;
+  phi_r0 = NULL;
+  sigma_rc = NULL;
+  pi_rc = NULL;
+  phi_rc = NULL;
+  r1 = NULL;
+  sigma_beta0 = NULL;
+  pi_beta0 = NULL;
+  phi0 = NULL;
+  sigma_n = NULL;
+  pi_n = NULL;
+  phi_m = NULL;
+  sigma_nc = NULL;
+  pi_nc = NULL;
+  phi_nc = NULL;
+  pro = NULL;
+  sigma_delta = NULL;
+  sigma_c = NULL;
+  sigma_a = NULL;
+  sigma_g0 = NULL;
+  sigma_g1 = NULL;
+  sigma_g2 = NULL;
+  sigma_g3 = NULL;
+  sigma_g4 = NULL;
+  sigma_f = NULL;
+  sigma_k = NULL;
+  small3 = NULL;
+  rcut = NULL;
+  dr = NULL;
+  rdr = NULL;
+  disij = NULL;
+  rij = NULL;
+  cosAng = NULL;
+  betaS = NULL;
+  dBetaS = NULL;
+  betaP = NULL;
+  dBetaP = NULL;
+  repul = NULL;
+  dRepul = NULL;
+  itypeSigBk = NULL;
+  nSigBk = NULL;
+  sigB = NULL;
+  sigB1 = NULL;
+  itypePiBk = NULL;
+  nPiBk = NULL;
+  piB = NULL;
+  pBetaS = NULL;
+  pBetaS1 = NULL;
+  pBetaS2 = NULL;
+  pBetaS3 = NULL;
+  pBetaS4 = NULL;
+  pBetaS5 = NULL;
+  pBetaS6 = NULL;
+  pBetaP = NULL;
+  pBetaP1 = NULL;
+  pBetaP2 = NULL;
+  pBetaP3 = NULL;
+  pBetaP4 = NULL;
+  pBetaP5 = NULL;
+  pBetaP6 = NULL;
+  pRepul = NULL;
+  pRepul1 = NULL;
+  pRepul2 = NULL;
+  pRepul3 = NULL;
+  pRepul4 = NULL;
+  pRepul5 = NULL;
+  pRepul6 = NULL;
+  FsigBO = NULL;
+  FsigBO1 = NULL;
+  FsigBO2 = NULL;
+  FsigBO3 = NULL;
+  FsigBO4 = NULL;
+  FsigBO5 = NULL;
+  FsigBO6 = NULL;
+  rcmin = NULL;
+  rcmax = NULL;
+  rcmaxp = NULL;
+  setflag = NULL;
+  cutsq = NULL;
+  cutghost = NULL;
+
+  ghostneigh = 1;
+  bt_sg=NULL;
+  bt_pi=NULL;
+}
+
+/* ----------------------------------------------------------------------
+   check if allocated, since class can be destructed when incomplete
+------------------------------------------------------------------------- */
+
+PairBOP::~PairBOP()
+{
+  int i;
+  if(allocated) {
+    memory_theta_destroy();
+    if(otfly==0) 
+      memory->destroy(cos_index);
+    delete [] map;
+    memory->destroy(BOP_index);
+    memory->destroy(rcut);
+    memory->destroy(dr);
+    memory->destroy(rdr);
+    memory->destroy(setflag);
+    memory->destroy(cutsq);
+    memory->destroy(cutghost);
+    memory->destroy(pBetaS);
+    memory->destroy(pBetaS1);
+    memory->destroy(pBetaS2);
+    memory->destroy(pBetaS3);
+    memory->destroy(pBetaS4);
+    memory->destroy(pBetaS5);
+    memory->destroy(pBetaS6);
+    memory->destroy(pBetaP);
+    memory->destroy(pBetaP1);
+    memory->destroy(pBetaP2);
+    memory->destroy(pBetaP3);
+    memory->destroy(pBetaP4);
+    memory->destroy(pBetaP5);
+    memory->destroy(pBetaP6);
+    memory->destroy(pRepul);
+    memory->destroy(pRepul1);
+    memory->destroy(pRepul2);
+    memory->destroy(pRepul3);
+    memory->destroy(pRepul4);
+    memory->destroy(pRepul5);
+    memory->destroy(pRepul6);
+    memory->destroy(FsigBO);
+    memory->destroy(FsigBO1);
+    memory->destroy(FsigBO2);
+    memory->destroy(FsigBO3);
+    memory->destroy(FsigBO4);
+    memory->destroy(FsigBO5);
+    memory->destroy(FsigBO6);
+    if(table==0) {
+      memory->destroy(pi_a);
+      memory->destroy(pro_delta);
+      memory->destroy(pi_delta);
+      memory->destroy(pi_p);
+      memory->destroy(pi_c);
+      memory->destroy(sigma_r0);
+      memory->destroy(pi_r0);
+      memory->destroy(phi_r0);
+      memory->destroy(sigma_rc);
+      memory->destroy(pi_rc);
+      memory->destroy(phi_rc);
+      memory->destroy(r1);
+      memory->destroy(sigma_beta0);
+      memory->destroy(pi_beta0);
+      memory->destroy(phi0);
+      memory->destroy(sigma_n);
+      memory->destroy(pi_n);
+      memory->destroy(phi_m);
+      memory->destroy(sigma_nc);
+      memory->destroy(pi_nc);
+      memory->destroy(phi_nc);
+      memory->destroy(pro);
+      memory->destroy(sigma_delta);
+      memory->destroy(sigma_c);
+      memory->destroy(sigma_a);
+      memory->destroy(sigma_g0);
+      memory->destroy(sigma_g1);
+      memory->destroy(sigma_g2);
+      memory->destroy(sigma_g3);
+      memory->destroy(sigma_g4);
+      memory->destroy(sigma_f);
+      memory->destroy(sigma_k);
+      memory->destroy(small3);
+    }
+    else {
+      memory->destroy(pi_a);
+      memory->destroy(pro_delta);
+      memory->destroy(pi_delta);
+      memory->destroy(pi_p);
+      memory->destroy(pi_c);
+      memory->destroy(r1);
+      memory->destroy(pro);
+      memory->destroy(sigma_delta);
+      memory->destroy(sigma_c);
+      memory->destroy(sigma_a);
+      memory->destroy(sigma_g0);
+      memory->destroy(sigma_g1);
+      memory->destroy(sigma_g2);
+      memory->destroy(sigma_f);
+      memory->destroy(sigma_k);
+      memory->destroy(small3);
+    }
+  }
+  if(allocate_sigma) {
+    destroy_sigma();
+  }
+  if(allocate_pi) {
+    destroy_pi();
+  }
+}
+
+/* ---------------------------------------------------------------------- */
+
+void PairBOP::compute(int eflag, int vflag)
+{
+  int ago,delay,every;
+  int i,j,ii,jj,iij;
+  int n,inum,temp_ij,ks;
+  int itype,jtype,i_tag,j_tag;
+  int *ilist,*iilist,*numneigh;
+  int **firstneigh;
+  double dpr1,ps;
+  double ftmp1,ftmp2,ftmp3,dE;
+  double dis_ij[3],rsq_ij,r_ij;
+  double betaS_ij,dBetaS_ij;
+  double betaP_ij,dBetaP_ij;
+  double repul_ij,dRepul_ij;
+  double totE;
+
+  double **f = atom->f;
+  double **x = atom->x;
+  int *type = atom->type;
+  int *tag = atom->tag;
+  int newton_pair = force->newton_pair;
+  int nlocal = atom->nlocal;
+  int nall = nlocal + atom->nghost;
+ 
+  inum = list->inum;
+  ilist = list->ilist;
+  numneigh = list->numneigh;
+  firstneigh = list->firstneigh;
+  ago=neighbor->ago;
+  delay=neighbor->delay;
+  every=neighbor->every;
+
+  if (eflag || vflag) ev_setup(eflag,vflag);
+  else evflag = vflag_fdotr = 0;
+
+// BOP Neighbor lists must be updated every time
+// atoms are moved between processors
+
+  if((ago ==0)||bop_step==0||(ago>=delay&&(ago%every)==0)||(nall>maxnall))
+    {
+      gneigh();
+    }
+
+// For non on the fly calculations cos and derivatives
+// are calculated in advance and stored
+
+  if(otfly==0) {
+    theta();
+  }
+  else {
+    theta_mod();
+  }
+
+// Calculate Sigma Bond-Order
+
+  if(a_flag==1) { 
+    if(otfly==0) {
+      sigmaBo_noa();
+    }
+    else {
+      sigmaBo_noa_otf();
+    }
+  }
+  else {
+    if(otfly==0) {
+      sigmaBo();
+    }
+    else {
+      sigmaBo_otf();
+    }
+  }
+
+// Calculate Pi Bond-Order
+
+  if(otfly==0) {
+    PiBo();
+  }
+  else {
+    PiBo_otf();
+  }
+  n=0; 
+  totE=0;
+  for (ii = 0; ii < inum; ii++) {
+    i=ilist[ii];
+    i_tag=tag[i];
+    itype=map[type[i]]+1;
+    iilist=firstneigh[i];
+    for(jj=0;jj<numneigh[i];jj++) {
+      temp_ij=BOP_index[i]+jj;
+      if(temp_ij>=neigh_total) {
+        printf("temp_ij is too big %7d\n",temp_ij);
+        exit(1);
+      }
+      j=iilist[jj];
+      j_tag=tag[j];
+      jtype=map[type[j]]+1;
+      if(j_tag>=i_tag) {
+        if(otfly==0) {
+          if(n>=neigh_total) {
+            printf("n is too big %7d\n",n);
+            exit(1);
+          }
+          if(neigh_flag[temp_ij]) {
+            dpr1=(dRepul[temp_ij]-2.0*dBetaS[temp_ij]*sigB[n]
+                -2.0*dBetaP[temp_ij]*piB[n])/rij[temp_ij];
+            ftmp1=dpr1*disij[0][temp_ij];
+            ftmp2=dpr1*disij[1][temp_ij];
+            ftmp3=dpr1*disij[2][temp_ij];
+            f[i][0]=f[i][0]+ftmp1;
+            f[i][1]=f[i][1]+ftmp2;
+            f[i][2]=f[i][2]+ftmp3;
+            f[j][0]=f[j][0]-ftmp1;
+            f[j][1]=f[j][1]-ftmp2;
+            f[j][2]=f[j][2]-ftmp3;
+
+//add repulsive and bond order components to total energy 
+//(d) Eq.1
+
+            dE=-2.0*betaS[temp_ij]*sigB[n]-2.0*betaP[temp_ij]*piB[n];
+            totE+=dE+repul[temp_ij];
+            if(evflag) { 
+              ev_tally_full(i,repul[temp_ij],dE,0.0,0.0,0.0,0.0);
+              ev_tally_full(j,repul[temp_ij],dE,0.0,0.0,0.0,0.0);
+              ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,-ftmp1,-ftmp2,-ftmp3,
+                  disij[0][temp_ij],disij[1][temp_ij],disij[2][temp_ij]);
+            }
+            n++;
+          }
+        }
+        else {
+          if(itype==jtype)
+            iij=itype-1;
+          else if(itype<jtype)
+            iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+          else
+            iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+          dis_ij[0]=x[j][0]-x[i][0]; 
+          dis_ij[1]=x[j][1]-x[i][1]; 
+          dis_ij[2]=x[j][2]-x[i][2]; 
+          rsq_ij=dis_ij[0]*dis_ij[0]
+              +dis_ij[1]*dis_ij[1]
+              +dis_ij[2]*dis_ij[2];
+          r_ij=sqrt(rsq_ij); 
+          if(r_ij<=rcut[iij]) {
+            ps=r_ij*rdr[iij]+1.0;
+            ks=(int)ps;
+            if(nr-1<ks)
+              ks=nr-1;
+            ps=ps-ks;
+            if(ps>1.0)
+              ps=1.0;
+            betaS_ij=((pBetaS3[iij][ks-1]*ps+pBetaS2[iij][ks-1])*ps
+                +pBetaS1[iij][ks-1])*ps+pBetaS[iij][ks-1];
+            dBetaS_ij=(pBetaS6[iij][ks-1]*ps+pBetaS5[iij][ks-1])*ps
+                +pBetaS4[iij][ks-1];
+            betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+                +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+            dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+                +pBetaP4[iij][ks-1];
+            repul_ij=((pRepul3[iij][ks-1]*ps+pRepul2[iij][ks-1])*ps
+                +pRepul1[iij][ks-1])*ps+pRepul[iij][ks-1];
+            dRepul_ij=(pRepul6[iij][ks-1]*ps+pRepul5[iij][ks-1])*ps
+                +pRepul4[iij][ks-1];
+            dpr1=(dRepul_ij-2.0*dBetaS_ij*sigB[n]
+                -2.0*dBetaP_ij*piB[n])/r_ij;
+            ftmp1=dpr1*dis_ij[0];
+            ftmp2=dpr1*dis_ij[1];
+            ftmp3=dpr1*dis_ij[2];
+            f[i][0]=f[i][0]+ftmp1;
+            f[i][1]=f[i][1]+ftmp2;
+            f[i][2]=f[i][2]+ftmp3;
+            f[j][0]=f[j][0]-ftmp1;
+            f[j][1]=f[j][1]-ftmp2;
+            f[j][2]=f[j][2]-ftmp3;
+
+//add repulsive and bond order components to total energy 
+//(d) Eq. 1 
+
+            dE=-2.0*betaS_ij*sigB[n]-2.0*betaP_ij*piB[n];
+            totE+=dE+repul_ij;
+            if(evflag) { 
+              ev_tally_full(i,repul_ij,dE,0.0,0.0,0.0,0.0);
+              ev_tally_full(j,repul_ij,dE,0.0,0.0,0.0,0.0);
+              ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,-ftmp1,-ftmp2,-ftmp3,
+                  dis_ij[0],dis_ij[1],dis_ij[2]);
+            }
+            n++;
+          }
+        }
+      }
+    }
+  }
+  if (vflag_fdotr) virial_fdotr_compute();
+  bop_step=1;
+}
+
+/* ----------------------------------------------------------------------
+   allocate all arrays
+------------------------------------------------------------------------- */
+
+void PairBOP::allocate()
+{
+  allocated = 1;
+  int n = atom->ntypes;
+  
+  memory->create(rcut,npairs,"BOP:rcut");
+  memory->create(dr,npairs,"BOP:dr");
+  memory->create(rdr,npairs,"BOP:dr");
+  memory->create(setflag,n+1,n+1,"pair:setflag");
+  memory->create(cutsq,n+1,n+1,"pair:cutsq");
+  memory->create(cutghost,n+1,n+1,"pair:cutghost");
+  memory->create(pBetaS,npairs,nr,"BOP:pBetaS");
+  memory->create(pBetaS1,npairs,nr,"BOP:pBetaS1");
+  memory->create(pBetaS2,npairs,nr,"BOP:pBetaS2");
+  memory->create(pBetaS3,npairs,nr,"BOP:pBetaS3");
+  memory->create(pBetaS4,npairs,nr,"BOP:pBetaS4");
+  memory->create(pBetaS5,npairs,nr,"BOP:pBetaS5");
+  memory->create(pBetaS6,npairs,nr,"BOP:pBetaS6");
+  memory->create(pBetaP,npairs,nr,"BOP:pBetaP");
+  memory->create(pBetaP1,npairs,nr,"BOP:pBetaP1");
+  memory->create(pBetaP2,npairs,nr,"BOP:pBetaP2");
+  memory->create(pBetaP3,npairs,nr,"BOP:pBetaP3");
+  memory->create(pBetaP4,npairs,nr,"BOP:pBetaP4");
+  memory->create(pBetaP5,npairs,nr,"BOP:pBetaP5");
+  memory->create(pBetaP6,npairs,nr,"BOP:pBetaP6");
+  memory->create(pRepul,npairs,nr,"BOP:pRepul");
+  memory->create(pRepul1,npairs,nr,"BOP:pRepul1");
+  memory->create(pRepul2,npairs,nr,"BOP:pRepul2");
+  memory->create(pRepul3,npairs,nr,"BOP:pRepul3");
+  memory->create(pRepul4,npairs,nr,"BOP:pRepul4");
+  memory->create(pRepul5,npairs,nr,"BOP:pRepul5");
+  memory->create(pRepul6,npairs,nr,"BOP:pRepul6");
+  memory->create(FsigBO,npairs,nBOt,"BOP:FsigBO");
+  memory->create(FsigBO1,npairs,nBOt,"BOP:FsigBO1");
+  memory->create(FsigBO2,npairs,nBOt,"BOP:FsigBO2");
+  memory->create(FsigBO3,npairs,nBOt,"BOP:FsigBO3");
+  memory->create(FsigBO4,npairs,nBOt,"BOP:FsigBO4");
+  memory->create(FsigBO5,npairs,nBOt,"BOP:FsigBO5");
+  memory->create(FsigBO6,npairs,nBOt,"BOP:FsigBO6");
+}
+
+/* ----------------------------------------------------------------------
+   global settings
+------------------------------------------------------------------------- */
+
+void PairBOP::settings(int narg, char **arg)
+{
+  if(narg!=0) error->all (FLERR,"Illegal pair_style command");
+}
+
+/* ----------------------------------------------------------------------
+   set coeffs for one or more type pairs(Updated: D.K. Ward 05/06/10)
+------------------------------------------------------------------------- */
+
+void PairBOP::coeff(int narg, char **arg)
+{
+  int i,j,n;
+  MPI_Comm_rank(world,&me);
+  map = new int[atom->ntypes+1];
+
+//These are predefined for use when generating table
+//If tables are being read in they can be changed
+ 
+  nr=2000;
+  nBOt=2000;
+  table=0;
+  bop_step=0;
+  nb_pi=0;
+  nb_sg=0;
+  allocate_sigma=0;
+  allocate_pi=0;
+  allocate_neigh=0;
+  update_list=0;
+  a_flag=0;
+
+  if (narg < 5 + atom->ntypes || narg > 7 + atom->ntypes)
+    error->all(FLERR,"Incorrect args for pair coefficients first");
+
+// ensure I,J args are * *
+
+  if (strcmp(arg[0],"*") != 0 || strcmp(arg[1],"*") != 0)
+    error->all(FLERR,"Incorrect args for pair coefficients second");
+
+  if (narg > 5 + atom->ntypes) {
+    if(strstr(arg[5+atom->ntypes],"table")!=NULL)
+      table=1;
+    else if(strstr(arg[5+atom->ntypes],"no_a")!=NULL)
+      a_flag=1;
+    else
+      error->all(FLERR,"Incorrect args for pair coefficients");
+  }
+  if (narg > 6 + atom->ntypes) {
+    if(strstr(arg[6+atom->ntypes],"table")!=NULL)
+      table=1;
+    else if(strstr(arg[6+atom->ntypes],"no_a")!=NULL)
+      a_flag=1;
+    else
+      error->all(FLERR,"Incorrect args for pair coefficients");
+  }
+  for(i=0;i<atom->ntypes;i++) {
+    if(strstr(arg[5+i],"table")!=NULL)
+      error->all(FLERR,"Incorrect args for pair coefficients");
+    if(strstr(arg[5+i],"no_a")!=NULL)
+      error->all(FLERR,"Incorrect args for pair coefficients");
+  }
+
+  if(table==0) {
+    read_file(arg[2]);
+  }
+  else {
+    read_table(arg[2]);
+  }
+  if(me==0) { 
+    if(narg==5+atom->ntypes) {
+      for (i = 5; i < narg; i++) {
+        if (strcmp(arg[i],"NULL") == 0) {
+          map[i-4] = -1;
+          continue;
+        }   
+        for (j = 0; j < bop_types; j++)
+          if (strcmp(arg[i],words[j]) == 0) break;
+        map[i-4] = j;
+      }
+    }
+    else {
+      for (i = 5; i < 5+atom->ntypes; i++) {
+        if (strcmp(arg[i],"NULL") == 0) {
+          map[i-4] = -1;
+          continue;
+        } 
+        for (j = 0; j < bop_types; j++) {
+          if (strcmp(arg[i],words[j]) == 0) break;
+        }
+        map[i-4] = j;
+      }
+    }
+  }
+  MPI_Bcast(&map[0],atom->ntypes+1,MPI_INT,0,world);
+  if(strstr(arg[4],"off")!=NULL)
+    otfly=0;
+  else if(strstr(arg[4],"on")!=NULL)
+    otfly=1;
+  else
+    error->all(FLERR,"Incorrect args for BOP on the fly settings");
+
+// read potential file and initialize fitting splines
+
+  if(table==0) {
+    setPbetaS();
+    setPbetaP();
+    setPrepul();
+    setSign();
+  }
+  n = atom->ntypes;
+  for(int i = 1; i<=n; i++)
+    for(int j =i;j<=n;j++)
+      setflag[i][j] = 0;  
+
+  int count =0;
+  for( int i = 1;i<= n;i++)
+    for( int j = i; j <= n; j++) {
+      if (map[i] >= 0 && map[j] >= 0) {
+      setflag[i][j] = 1;
+      count++;
+      }
+    }
+  if (count == 0) error->all(FLERR,"Incorrect args for pair coefficients"); 
+  if(me==0) {
+    if (words) {
+      for (i = 0; i < bop_types; i++) delete [] words[i];
+      delete[] words;
+    }
+  }
+}
+
+/* ----------------------------------------------------------------------
+   init specific to this pair style
+------------------------------------------------------------------------- */
+
+void PairBOP::init_style()
+{
+  if (atom->tag_enable == 0)
+    error->all(FLERR,"Pair style BOP requires atom IDs");
+  if (force->newton_pair == 0)
+    error->all(FLERR,"Pair style BOP requires newton pair on");
+
+// need a full neighbor list
+
+  int irequest = neighbor->request(this);
+  neighbor->requests[irequest]->half = 0;
+  neighbor->requests[irequest]->full = 1;
+  neighbor->requests[irequest]->ghost = 1;
+}
+
+double PairBOP::init_one(int i, int j)
+{
+  int ij;
+  
+  if (setflag[i][j] == 0) error->all(FLERR,"All pair coeffs are not set");
+
+  int ii = map[i]+1;
+  int jj = map[j]+1;
+ 
+  if(ii==jj)
+    ij=ii-1;
+  else if(ii<jj)
+    ij=ii*bop_types-ii*(ii+1)/2+jj-1;
+  else
+    ij=jj*bop_types-jj*(jj+1)/2+ii-1;
+    
+  cutghost[i][j] = rcut[ij];
+  cutghost[j][i] = cutghost[i][j];
+  cutsq[i][j] = rcut[ij]*rcut[ij];
+  cutsq[j][i] = cutsq[i][j];
+  return rcut[ij];
+}
+
+/* ----------------------------------------------------------------------
+   create BOP neighbor list from main neighbor list
+   BOP neighbor list stores neighbors of ghost atoms
+   BOP requires neighbor's of k if k is a neighbor of
+   j and j is a neighbor of i
+------------------------------------------------------------------------- */
+
+void PairBOP::gneigh()
+{
+  int i,ii;
+  int *ilist,*numneigh;
+  int **firstneigh;
+  int nlocal = atom->nlocal;
+  int nall = nlocal + atom->nghost;
+
+  if(allocate_neigh==0) {
+    memory->create (BOP_index,nall,"BOP_index");
+    if(otfly==0)
+      memory->create (cos_index,nall,"cos_index");
+    allocate_neigh=1;
+  }
+  else {
+    memory->grow (BOP_index,nall,"BOP_index");
+    if(otfly==0) {
+      memory->grow (cos_index,nall,"cos_index");
+    }
+    allocate_neigh=1;
+  }
+  ilist = list->ilist;
+  numneigh = list->numneigh;
+  firstneigh = list->firstneigh;
+  if(bop_step==0) {
+    maxneigh=0;
+    maxnall=0;
+  }
+  neigh_total=0;
+  cos_total=0;
+  for (ii = 0; ii < nall; ii++) {
+    if(i<nlocal) {
+      i=ilist[ii];
+      if(numneigh[i]>maxneigh) {
+        maxneigh=numneigh[i];
+      }
+    }
+    else {
+      i=ii;
+      if(numneigh[i]>maxneigh) {
+        maxneigh=numneigh[i];
+      }
+    }
+    if(i>=nall) {
+      printf("BOP 1:MAJOR ERROR in atom numbers\n");
+      exit(1);
+    } 
+    BOP_index[i]=neigh_total;
+    neigh_total+=numneigh[i];
+    if(otfly==0) {
+      cos_index[i]=cos_total;
+      cos_total+=numneigh[i]*(numneigh[i]-1)/2;
+    }
+  }
+  maxnall=nall;
+}
+
+void PairBOP::theta()
+{
+  int i,j,k,ii,jj,kk;
+  int itype,jtype,i12;
+  int temp_ij,temp_ik,temp_ijk;
+  int n,nlocal,nall,ks;
+  int *ilist,*numneigh;
+  int *iilist;
+  int **firstneigh;
+  double rj2,rk2,rsq,ps;
+  double rj1k1,rj2k2,rj2k1,rj1k2;
+  double **x = atom->x;
+  int *type = atom->type;
+
+  nlocal = atom->nlocal;
+  nall = nlocal+atom->nghost;
+  ilist = list->ilist;
+  firstneigh = list->firstneigh;
+  numneigh = list->numneigh;
+  if(update_list!=0) 
+    memory_theta_grow();
+  else
+    memory_theta_create();
+  for (ii = 0; ii < nall; ii++) {
+    if(ii<nlocal)
+      i= ilist[ii];
+    else
+      i=ii;
+    itype = map[type[i]]+1;
+      
+    iilist=firstneigh[i];
+    for(jj=0;jj<numneigh[i];jj++) {
+      j=iilist[jj];
+      temp_ij=BOP_index[i]+jj;
+      if(temp_ij>=neigh_total) {
+        printf("BOP 2:ij neighbor error \n");
+        exit(1);
+      }
+      jtype = map[type[j]]+1;
+
+      if(itype==jtype)
+        i12=itype-1;
+      else if(itype<jtype)
+        i12=itype*bop_types-itype*(itype+1)/2+jtype-1;
+      else
+        i12=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+      if(i12>=npairs) {
+        printf("incorrect npairs allocated %7d \n",i12);
+        exit(1);
+      }
+      disij[0][temp_ij]=x[j][0]-x[i][0]; 
+      disij[1][temp_ij]=x[j][1]-x[i][1]; 
+      disij[2][temp_ij]=x[j][2]-x[i][2]; 
+      rsq=disij[0][temp_ij]*disij[0][temp_ij]
+          +disij[1][temp_ij]*disij[1][temp_ij]
+          +disij[2][temp_ij]*disij[2][temp_ij];
+      rij[temp_ij]=sqrt(rsq); 
+      if(rij[temp_ij]<=rcut[i12]) 
+        neigh_flag[temp_ij]=1;
+      else
+        neigh_flag[temp_ij]=0;
+      ps=rij[temp_ij]*rdr[i12]+1.0;
+      ks=(int)ps;
+
+      if(nr-1<ks)
+        ks=nr-1;
+      ps=ps-ks;
+      if(ps>1.0)
+        ps=1.0;
+      betaS[temp_ij]=((pBetaS3[i12][ks-1]*ps+pBetaS2[i12][ks-1])*ps
+          +pBetaS1[i12][ks-1])*ps+pBetaS[i12][ks-1];
+      dBetaS[temp_ij]=(pBetaS6[i12][ks-1]*ps+pBetaS5[i12][ks-1])*ps
+          +pBetaS4[i12][ks-1];
+      betaP[temp_ij]=((pBetaP3[i12][ks-1]*ps+pBetaP2[i12][ks-1])*ps
+          +pBetaP1[i12][ks-1])*ps+pBetaP[i12][ks-1];
+      dBetaP[temp_ij]=(pBetaP6[i12][ks-1]*ps+pBetaP5[i12][ks-1])*ps
+          +pBetaP4[i12][ks-1];
+      repul[temp_ij]=((pRepul3[i12][ks-1]*ps+pRepul2[i12][ks-1])*ps
+          +pRepul1[i12][ks-1])*ps+pRepul[i12][ks-1];
+      dRepul[temp_ij]=(pRepul6[i12][ks-1]*ps+pRepul5[i12][ks-1])*ps
+          +pRepul4[i12][ks-1];
+    }
+  }
+  for (ii = 0; ii < nall; ii++) {
+    n=0;
+    if(ii<nlocal)
+      i= ilist[ii];
+    else
+      i=ii;
+    iilist=firstneigh[i];
+    for(jj=0;jj<numneigh[i];jj++) {
+      j=iilist[jj];
+      temp_ij=BOP_index[i]+jj;
+      if(temp_ij>=neigh_total) {
+        printf("BOP 3:ij neighbor error \n");
+        exit(1);
+      }
+      rj2=rij[temp_ij]*rij[temp_ij];
+      for(kk=jj+1;kk<numneigh[i];kk++) {
+        if(cos_index[i]+n>=cos_total) {
+          printf("BOP 4:too large \n");
+          exit(1);
+        }
+        temp_ik=BOP_index[i]+kk;
+        if(temp_ik>=neigh_total) {
+          printf("BOP 5:ik neighbor error \n");
+          exit(1);
+        }
+        temp_ijk=cos_index[i]+n; 
+        if(temp_ijk>=cos_total) {
+          printf("BOP 6:ijk neighbor error \n");
+          exit(1);
+        }
+        rk2=rij[temp_ik]*rij[temp_ik];
+        rj1k1=rij[temp_ij]*rij[temp_ik];
+        rj2k2=rj1k1*rj1k1;
+        rj2k1=rj1k1*rij[temp_ij];
+        rj1k2=rj1k1*rij[temp_ik];
+        k=iilist[kk];
+        if(temp_ijk>=cos_total) {
+          printf("11 error in cos %7d\n",temp_ijk);
+          exit(1);
+        }
+        cosAng[temp_ijk]=(disij[0][temp_ij]*disij[0][temp_ik]+disij[1][temp_ij]
+            *disij[1][temp_ik]+disij[2][temp_ij]*disij[2][temp_ik])/rj1k1;
+        dcAng[temp_ijk][0][0]=(disij[0][temp_ik]*rj1k1-cosAng[temp_ijk]
+              *disij[0][temp_ij]*rk2)/(rj2k2);
+        dcAng[temp_ijk][1][0]=(disij[1][temp_ik]*rj1k1-cosAng[temp_ijk]
+            *disij[1][temp_ij]*rk2)/(rj2k2);
+        dcAng[temp_ijk][2][0]=(disij[2][temp_ik]*rj1k1-cosAng[temp_ijk]
+            *disij[2][temp_ij]*rk2)/(rj2k2);
+        dcAng[temp_ijk][0][1]=(disij[0][temp_ij]*rj1k1-cosAng[temp_ijk]
+            *disij[0][temp_ik]*rj2)/(rj2k2);
+        dcAng[temp_ijk][1][1]=(disij[1][temp_ij]*rj1k1-cosAng[temp_ijk]
+            *disij[1][temp_ik]*rj2)/(rj2k2);
+        dcAng[temp_ijk][2][1]=(disij[2][temp_ij]*rj1k1-cosAng[temp_ijk]
+            *disij[2][temp_ik]*rj2)/(rj2k2);
+        n++;
+      } 
+    }
+  }
+}
+
+void PairBOP::theta_mod()
+{
+  if(update_list!=0)
+    memory_theta_grow();
+  else
+    memory_theta_create();
+}
+
+/*  The formulation differs slightly to avoid negative square roots
+    in the calculation of Sigma^(1/2) of (a) Eq. 6 and (b) Eq. 11 */
+ 
+void PairBOP::sigmaBo()
+{
+  int nb_t,new_n_tot;
+  int n,i,j,k,kp,m,pp,kkp;
+  int iij,ji,ki;
+  int itmp,jtmp,ktmp,ltmp,mtmp;
+  int i_tag,j_tag;
+  int ngi,ngj,ngk,nglkp,ngli,nglj,ngl;
+  int ngji,ngjk,nikj,ngki,ngkj,ngjkp;
+  int ngkpk,ngkpj,ngkkp,nglk;
+  int njik,nijk,nikkp,nkp,nijkp;
+  int nkikp,njikp,nk0;
+  int njkpk,nkjkp,njkkp;
+  int jNeik,kNeii,kNeij,kNeikp;
+  int kpNeij,kpNeik;
+  int new1,new2,nlocal;
+  int inum,*ilist,*iilist,*jlist,*klist,*kplist;
+  int **firstneigh,*numneigh;
+  int temp_ji,temp_ikp,temp_ki,temp_kkp;
+  int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+  int ang_ijkp,ang_ikkp,ang_jkpk,ang_kjkp;
+  int ang_ijk,ang_ikj,ang_jikp,ang_jkkp;
+  int ang_jik,ang_kikp;
+  int nb_ij,nb_ik,nb_ikp;
+  int nb_jk,nb_jkp,nb_kkp;
+  int kp_nsearch,nsearch;
+  int sig_flag,setting,ncmp,ks;
+  int itype,jtype,ktype,kptype;
+  int bt_i,bt_j,bt_ij;
+  int kp_index,same_ikp,same_jkp;
+  int same_kkp,same_jkpj;
+  double AA,BB,CC,DD,EE,EE1,FF;
+  double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+  double AACFF,UT,bndtmp,UTcom;
+  double amean,gmean0,gmean1,gmean2,ps;
+  double gfactor1,gprime1,gsqprime,factorsq;
+  double gfactorsq,gfactor2,gprime2;
+  double gfactorsq2,gsqprime2;
+  double gfactor3,gprime3,gfactor,rfactor;
+  double drfactor,gfactor4,gprime4,agpdpr3;
+  double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+  double rcm1,rcm2,gcm1,gcm2,gcm3;
+  double agpdpr1,agpdpr2,app1,app2,app3,app4;
+  double dsigB1,dsigB2;
+  double part0,part1,part2,part3,part4;
+  double psign,bndtmp0,pp1;
+  double bndtmp1,bndtmp2,bndtmp3,bndtmp4,bndtmp5;
+  double ftmp[3];
+  double **x = atom->x;
+  double **f = atom->f;
+  int *tag = atom->tag;
+  int newton_pair = force->newton_pair;
+  int *type = atom->type;
+
+  nlocal = atom->nlocal;
+  int nall = nlocal+atom->nghost;
+  firstneigh = list->firstneigh;
+  numneigh = list->numneigh;
+  inum = list->inum; 
+  ilist = list->ilist;
+  n=0;
+
+//loop over all local atoms
+
+  if(nb_sg>16) {
+    nb_sg=16;
+  }
+  if(nb_sg==0) {
+    nb_sg=(maxneigh)*(maxneigh/2);
+  }
+  if(allocate_sigma) {
+    destroy_sigma();
+  }
+  create_sigma(nb_sg);
+  for(itmp=0;itmp<inum;itmp++) {
+    i = ilist[itmp];
+    i_tag=tag[i];  
+    itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+
+    for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+      temp_ij=BOP_index[i]+jtmp;
+      if(neigh_flag[temp_ij]) {
+        for(m=0;m<nb_sg;m++) {
+          for(pp=0;pp<3;pp++) {
+            bt_sg[m].dAA[pp]=0.0;
+            bt_sg[m].dBB[pp]=0.0;
+            bt_sg[m].dCC[pp]=0.0;
+            bt_sg[m].dDD[pp]=0.0;
+            bt_sg[m].dEE[pp]=0.0;
+            bt_sg[m].dEE1[pp]=0.0;
+            bt_sg[m].dFF[pp]=0.0;
+            bt_sg[m].dAAC[pp]=0.0;
+            bt_sg[m].dBBC[pp]=0.0;
+            bt_sg[m].dCCC[pp]=0.0;
+            bt_sg[m].dDDC[pp]=0.0;
+            bt_sg[m].dEEC[pp]=0.0;
+            bt_sg[m].dFFC[pp]=0.0;
+            bt_sg[m].dGGC[pp]=0.0;
+            bt_sg[m].dUT[pp]=0.0;
+            bt_sg[m].dSigB1[pp]=0.0;
+            bt_sg[m].dSigB[pp]=0.0;
+          }
+          bt_sg[m].i=-1;
+          bt_sg[m].j=-1;
+          bt_sg[m].temp=-1;
+        }
+        nb_t=0;
+        iilist=firstneigh[i];
+        j=iilist[jtmp];
+        jlist=firstneigh[j];
+        for(ki=0;ki<numneigh[j];ki++) {
+          temp_ki=BOP_index[j]+ki;
+          if(x[jlist[ki]][0]==x[i][0]) {
+            if(x[jlist[ki]][1]==x[i][1]) {
+              if(x[jlist[ki]][2]==x[i][2]) {
+                if(!neigh_flag[temp_ki]) {
+                  printf("BOP 7:error 1 flag %7d temp %7d %7d\n",neigh_flag[temp_ki],temp_ki,temp_ij);
+                  exit(1);
+                }
+                break;
+              }
+            }
+          }
+        }
+        j_tag=tag[j];
+        jtype = map[type[j]]+1;
+        nb_ij=nb_t;
+        nb_t++;
+        if(nb_t>nb_sg) {
+          new_n_tot=nb_sg+maxneigh;
+          grow_sigma(nb_sg,new_n_tot);
+          nb_sg=new_n_tot;
+        }
+        bt_sg[nb_ij].temp=temp_ij;
+        bt_sg[nb_ij].i=i;
+        bt_sg[nb_ij].j=j;
+        if(j_tag>=i_tag) {
+          if(n>=neigh_total) {
+            printf("BOP 9:n is too large \n");
+            exit(1);
+          }
+          if(itype==jtype)
+            iij=itype-1;
+          else if(itype<jtype)
+            iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+          else
+            iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+          for(ji=0;ji<numneigh[j];ji++) {
+            temp_ji=BOP_index[j]+ji;
+            if(x[jlist[ji]][0]==x[i][0]) {
+              if(x[jlist[ji]][1]==x[i][1]) {
+                if(x[jlist[ji]][2]==x[i][2]) {
+                  break;
+                }
+              }
+            }
+          }
+          nSigBk[n]=0;
+
+//AA-EE1 are the components making up Eq. 30 (a)
+
+          AA=0.0;
+          BB=0.0;
+          CC=0.0;
+          DD=0.0;
+          EE=0.0;
+          EE1=0.0;
+
+//FF is the Beta_sigma^2 term
+       
+          FF=betaS[temp_ij]*betaS[temp_ij];
+
+//agpdpr1 is derivative of FF w.r.t. r_ij
+
+          agpdpr1=2.0*betaS[temp_ij]*dBetaS[temp_ij]/rij[temp_ij];
+
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+
+          bt_sg[nb_ij].dFF[0]=agpdpr1*disij[0][temp_ij];
+          bt_sg[nb_ij].dFF[1]=agpdpr1*disij[1][temp_ij];
+          bt_sg[nb_ij].dFF[2]=agpdpr1*disij[2][temp_ij];
+
+//k is loop over all neighbors of i again with j neighbor of i 
+
+          for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+            temp_ik=BOP_index[i]+ktmp;       
+            if(neigh_flag[temp_ik]) {
+              if(ktmp!=jtmp) {
+                if(jtmp<ktmp) {
+                  njik=jtmp*(2*numneigh[i]-jtmp-1)/2+(ktmp-jtmp)-1;
+                  ngj=0;
+                  ngk=1;
+                }
+                else {
+                  njik=ktmp*(2*numneigh[i]-ktmp-1)/2+(jtmp-ktmp)-1;
+                  ngj=1;
+                  ngk=0;
+                }
+                k=iilist[ktmp];
+                ktype = map[type[k]]+1;
+
+//find neighbor of k that is equal to i
+
+                klist=firstneigh[k];
+                for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+                  temp_ki=BOP_index[k]+kNeii;
+                  if(x[klist[kNeii]][0]==x[i][0]) {
+                    if(x[klist[kNeii]][1]==x[i][1]) {
+                      if(x[klist[kNeii]][2]==x[i][2]) {
+                        if(!neigh_flag[temp_ki]) {
+                          printf("BOP 8:error 2 flag %7d temp %7d %7d\n",neigh_flag[temp_ki],temp_ki,temp_ij);
+                          exit(1);
+                        }
+                        break;
+                      }
+                    }
+                  }
+                }
+
+//find neighbor of i that is equal to k
+
+                for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+                  temp_jk=BOP_index[j]+jNeik;
+                  if(x[jlist[jNeik]][0]==x[k][0]) {
+                    if(x[jlist[jNeik]][1]==x[k][1]) {
+                      if(x[jlist[jNeik]][2]==x[k][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+
+//find neighbor of k that is equal to j
+
+                for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                  if(x[klist[kNeij]][0]==x[j][0]) {
+                    if(x[klist[kNeij]][1]==x[j][1]) {
+                      if(x[klist[kNeij]][2]==x[j][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+                sig_flag=0;
+                if(nSigBk[n]>neigh_ct) {
+                  printf("1 too big nSigBk\n");
+                  exit(1);
+                }
+                for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                  ncmp=itypeSigBk[n][nsearch];
+                  if(x[ncmp][0]==x[k][0]) {
+                    if(x[ncmp][1]==x[k][1]) {
+                      if(x[ncmp][2]==x[k][2]) {
+                        nk0=nsearch;
+                        sig_flag=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(sig_flag==0) {
+                  nSigBk[n]=nSigBk[n]+1;
+                  nk0=nSigBk[n]-1;
+                  if(nk0>=neigh_ct) {
+                    printf("2 too big nSigBk\n");
+                    exit(1);
+                  }
+                  itypeSigBk[n][nk0]=k;
+                }
+                nb_ik=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_ik].temp=temp_ik;
+                bt_sg[nb_ik].i=i;
+                bt_sg[nb_ik].j=k;
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                ang_jik=cos_index[i]+njik;
+                gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+                gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+                gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+                amean=cosAng[ang_jik];
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gsqprime=2.0*gfactor1*gprime1;
+
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+
+                AA=AA+gfactorsq*betaS[temp_ik]*betaS[temp_ik];
+                CC=CC+gfactorsq*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik];
+
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//agpdpr2 is derivative of CC 1st term w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+//app2 is derivative of CC 1st term w.r.t. cos(theta_jik)
+
+                agpdpr1=2.0*gfactorsq*betaS[temp_ik]*dBetaS[temp_ik]/rij[temp_ik];
+                agpdpr1=2.0*betaS[temp_ik]*betaS[temp_ik]*agpdpr1;
+                app1=betaS[temp_ik]*betaS[temp_ik]*gsqprime;
+                app1=betaS[temp_ik]*betaS[temp_ik]*app1;
+                bt_sg[nb_ij].dAA[0]+=
+                    app1*dcAng[ang_jik][0][ngj];
+                bt_sg[nb_ij].dAA[1]+=
+                    app1*dcAng[ang_jik][1][ngj];
+                bt_sg[nb_ij].dAA[2]+=
+                    app1*dcAng[ang_jik][2][ngj];
+                bt_sg[nb_ij].dCC[0]+=
+                    app2*dcAng[ang_jik][0][ngj];
+                bt_sg[nb_ij].dCC[1]+=
+                    app2*dcAng[ang_jik][1][ngj];
+                bt_sg[nb_ij].dCC[2]+=
+                    app2*dcAng[ang_jik][2][ngj];
+                bt_sg[nb_ik].dAA[0]+=
+                    app1*dcAng[ang_jik][0][ngk]
+                    +agpdpr1*disij[0][temp_ik];
+                bt_sg[nb_ik].dAA[1]+=
+                    app1*dcAng[ang_jik][1][ngk]
+                    +agpdpr1*disij[1][temp_ik];
+                bt_sg[nb_ik].dAA[2]+=
+                    app1*dcAng[ang_jik][2][ngk]
+                    +agpdpr1*disij[2][temp_ik];
+                bt_sg[nb_ik].dCC[0]+=
+                    app2*dcAng[ang_jik][0][ngk]
+                    +agpdpr2*disij[0][temp_ik];
+                bt_sg[nb_ik].dCC[1]+=
+                    app2*dcAng[ang_jik][1][ngk]
+                    +agpdpr2*disij[1][temp_ik];
+                bt_sg[nb_ik].dCC[2]+=
+                    app2*dcAng[ang_jik][2][ngk]
+                    +agpdpr2*disij[2][temp_ik];
+
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k 
+
+                kp_index=0;
+                for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+                  temp_jkp=BOP_index[j]+ltmp;
+                  kp=jlist[ltmp];
+                  if(x[kp][0]==x[k][0]) {
+                    if(x[kp][1]==x[k][1]) {
+                      if(x[kp][2]==x[k][2]) {
+                        kp_index=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(kp_index) {
+
+//loop over neighbors of k
+
+                  for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+                    kp=klist[mtmp];
+                    if(x[kp][0]==x[j][0]) {
+                      if(x[kp][1]==x[j][1]) {
+                        if(x[kp][2]==x[j][2]) {
+                          break;
+                        }
+                      }
+                    }
+                  }
+                  if(ki<ltmp) {
+                    nijk=ki*(2*numneigh[j]-ki-1)/2+(ltmp-ki)-1;
+                    ngji=0;
+                    ngjk=1;
+                  }
+                  else {
+                    nijk=ltmp*(2*numneigh[j]-ltmp-1)/2+(ki-ltmp)-1;
+                    ngji=1;
+                    ngjk=0;
+                  }
+                  if(kNeii<mtmp) {
+                    nikj=kNeii*(2*numneigh[k]-kNeii-1)/2+(mtmp-kNeii)-1;
+                    ngki=0;
+                    ngkj=1;
+                  }
+                  else {
+                    nikj=mtmp*(2*numneigh[k]-mtmp-1)/2+(kNeii-mtmp)-1;
+                    ngki=1;
+                    ngkj=0;
+                  }
+                  ang_ijk=cos_index[j]+nijk;
+                  gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                  gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                  gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                  amean=cosAng[ang_ijk];
+                  gfactor2=gmean0+gmean1*amean
+                      +gmean2*amean*amean;
+                  gprime2=gmean1+2.0*gmean2*amean;
+                  gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+                  gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+                  gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+                  ang_ikj=cos_index[k]+nikj;
+                  amean=cosAng[ang_ikj];
+                  gfactor3=gmean0+gmean1*amean
+                      +gmean2*amean*amean;
+                  gprime3=gmean1+2.0*gmean2*amean;
+                  gfactor=gfactor1*gfactor2*gfactor3;
+                  rfactor=betaS[temp_ik]*betaS[temp_jkp];
+
+//EE1 is (b) Eq. 12
+
+                  EE1=EE1+gfactor*rfactor;
+
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+
+                  rcm1=gfactor*betaS[temp_jkp]*dBetaS[temp_ik]/rij[temp_ik];
+                  rcm2=gfactor*betaS[temp_ik]*dBetaS[temp_jkp]/rij[temp_jkp];
+                  gcm1=rfactor*gprime1*gfactor2*gfactor3;
+                  gcm2=rfactor*gfactor1*gprime2*gfactor3;
+                  gcm3=rfactor*gfactor1*gfactor2*gprime3;
+                  bt_sg[nb_ij].dEE1[0]+=
+                      gcm1*dcAng[ang_jik][0][ngj]
+                      -gcm2*dcAng[ang_ijk][0][ngji];
+                  bt_sg[nb_ij].dEE1[1]+=
+                      gcm1*dcAng[ang_jik][1][ngj]
+                      -gcm2*dcAng[ang_ijk][1][ngji];
+                  bt_sg[nb_ij].dEE1[2]+=
+                      gcm1*dcAng[ang_jik][2][ngj]
+                      -gcm2*dcAng[ang_ijk][2][ngji];
+                  bt_sg[nb_ik].dEE1[0]+=
+                      gcm1*dcAng[ang_jik][0][ngk]
+                      +rcm1*disij[0][temp_ik]
+                      -gcm3*dcAng[ang_ikj][0][ngki];
+                  bt_sg[nb_ik].dEE1[1]+=
+                      gcm1*dcAng[ang_jik][1][ngk]
+                      +rcm1*disij[1][temp_ik]
+                      -gcm3*dcAng[ang_ikj][1][ngki];
+                  bt_sg[nb_ik].dEE1[2]+=
+                      gcm1*dcAng[ang_jik][2][ngk]
+                      +rcm1*disij[2][temp_ik]
+                      -gcm3*dcAng[ang_ikj][2][ngki];
+                  bt_sg[nb_jk].dEE1[0]+=
+                      gcm2*dcAng[ang_ijk][0][ngjk]
+                      +rcm2*disij[0][temp_jkp]
+                      -gcm3*dcAng[ang_ikj][0][ngkj];
+                  bt_sg[nb_jk].dEE1[1]+=
+                      gcm2*dcAng[ang_ijk][1][ngjk]
+                      +rcm2*disij[1][temp_jkp]
+                      -gcm3*dcAng[ang_ikj][1][ngkj];
+                  bt_sg[nb_jk].dEE1[2]+=
+                      gcm2*dcAng[ang_ijk][2][ngjk]
+                      +rcm2*disij[2][temp_jkp]
+                      -gcm3*dcAng[ang_ikj][2][ngkj];
+                }
+
+// k and k' and j are all different neighbors of i
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=jtmp) {
+                    temp_ikp=BOP_index[i]+ltmp;
+                    if(neigh_flag[temp_ikp]) {
+                      kp=iilist[ltmp];
+                      kptype = map[type[kp]]+1;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("3 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(jtmp<ltmp) {
+                        njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+                        nglj=0;
+                        ngl=1;
+                      }
+                      else {
+                        njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+                        nglj=1;
+                        ngl=0;
+                      }
+                      if(ktmp<ltmp) {
+                        nkikp=ktmp*(2*numneigh[i]-ktmp-1)/2+(ltmp-ktmp)-1;
+                        nglk=0;
+                        nglkp=1;
+                      }
+                      else {
+                        nkikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(ktmp-ltmp)-1;
+                        nglk=1;
+                        nglkp=0;
+                      }
+                      ang_jikp=cos_index[i]+njikp;
+                      nb_ikp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_ikp].temp=temp_ikp;
+                      bt_sg[nb_ikp].i=i;
+                      bt_sg[nb_ikp].j=kp;
+                      gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+                      amean=cosAng[ang_jikp];
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+                      ang_kikp=cos_index[i]+nkikp;
+                      amean=cosAng[ang_kikp];
+                      gfactor3=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS[temp_ik]*betaS[temp_ikp];
+                      rfactor=rfactorrt*rfactorrt;
+
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+
+                      CC=CC+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of CC 2nd term w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of CC 2nd term w.r.t. Beta(r_ik')
+//app1 is derivative of CC 2nd term w.r.t. cos(theta_jik)
+//app2 is derivative of CC 2nd term w.r.t. cos(theta_jik')
+//app3 is derivative of CC 2nd term w.r.t. cos(theta_kik')
+ 
+                      agpdpr1=4.0*gfactor*rfactorrt*betaS[temp_ikp]
+                          *dBetaS[temp_ik]/rij[temp_ik];
+                      agpdpr2=4.0*gfactor*rfactorrt*betaS[temp_ik]
+                          *dBetaS[temp_ikp]/rij[temp_ikp];
+                      app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+                      app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+                      app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+                      bt_sg[nb_ij].dCC[0]+=
+                          app1*dcAng[ang_jik][0][ngj]
+                          +app2*dcAng[ang_jikp][0][nglj];
+                      bt_sg[nb_ij].dCC[1]+=
+                          app1*dcAng[ang_jik][1][ngj]
+                          +app2*dcAng[ang_jikp][1][nglj];
+                      bt_sg[nb_ij].dCC[2]+=
+                          app1*dcAng[ang_jik][2][ngj]
+                          +app2*dcAng[ang_jikp][2][nglj];
+                      bt_sg[nb_ik].dCC[0]+=
+                          app1*dcAng[ang_jik][0][ngk]
+                          +app3*dcAng[ang_kikp][0][nglk]
+                          +agpdpr1*disij[0][temp_ik];
+                      bt_sg[nb_ik].dCC[1]+=
+                          app1*dcAng[ang_jik][1][ngk]
+                          +app3*dcAng[ang_kikp][1][nglk]
+                          +agpdpr1*disij[1][temp_ik];
+                      bt_sg[nb_ik].dCC[2]+=
+                          app1*dcAng[ang_jik][2][ngk]
+                          +app3*dcAng[ang_kikp][2][nglk]
+                          +agpdpr1*disij[2][temp_ik];
+                      bt_sg[nb_ikp].dCC[0]+=
+                          app2*dcAng[ang_jikp][0][ngl]
+                          +app3*dcAng[ang_kikp][0][nglkp]
+                          +agpdpr2*disij[0][temp_ikp];
+                      bt_sg[nb_ikp].dCC[1]+=
+                          app2*dcAng[ang_jikp][1][ngl]
+                          +app3*dcAng[ang_kikp][1][nglkp]
+                          +agpdpr2*disij[1][temp_ikp];
+                      bt_sg[nb_ikp].dCC[2]+=
+                          app2*dcAng[ang_jikp][2][ngl]
+                          +app3*dcAng[ang_kikp][2][nglkp]
+                          +agpdpr2*disij[2][temp_ikp];
+                    }
+                  }
+                }
+
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  if(neigh_flag[temp_kkp]) {
+                    kp=klist[ltmp];;
+                    kptype = map[type[kp]]+1;
+                    same_ikp=0;
+                    same_jkp=0;
+                    if(x[i][0]==x[kp][0]) {
+                      if(x[i][1]==x[kp][1]) {
+                        if(x[i][2]==x[kp][2]) {
+                          same_ikp=1;
+                        }
+                      }
+                    }
+                    if(x[j][0]==x[kp][0]) {
+                      if(x[j][1]==x[kp][1]) {
+                        if(x[j][2]==x[kp][2]) {
+                          same_jkp=1;
+                        }
+                      }
+                    }
+                    if(!same_ikp&&!same_jkp) {
+                      if(kNeii<ltmp) {
+                        nikkp=kNeii*(2*numneigh[k]-kNeii-1)/2+(ltmp-kNeii)-1;
+                        nglkp=1;
+                        ngli=0;
+                      }
+                      else {
+                        nikkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeii-ltmp)-1;
+                        nglkp=0;
+                        ngli=1;
+                      }
+                      sig_flag=0;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("4 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              sig_flag=1;
+                              nkp=nsearch;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==0) {
+                        nSigBk[n]=nSigBk[n]+1;
+                        nkp=nSigBk[n]-1;
+                        if(nkp>=neigh_ct) {
+                          printf("5 too big nSigBk\n");
+                          exit(1);
+                        }
+                        itypeSigBk[n][nkp]=kp;
+                      }
+                      ang_ikkp=cos_index[k]+nikkp;
+                      nb_kkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_kkp].temp=temp_kkp;
+                      bt_sg[nb_kkp].i=k;
+                      bt_sg[nb_kkp].j=kp;
+                      gmean0=sigma_g0[itype-1][ktype-1][kptype-1];          
+                      gmean1=sigma_g1[itype-1][ktype-1][kptype-1];          
+                      gmean2=sigma_g2[itype-1][ktype-1][kptype-1];          
+                      amean=cosAng[ang_ikkp];
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS[temp_ik]*betaS[temp_kkp];
+                      rfactor=rfactorrt*rfactorrt;
+
+//3rd CC is third term of Eq. 11 (c) for i atom 
+//where j , k =neighbor of i & k' =neighbor of k
+
+                      CC=CC+gfactor*rfactor;
+                      agpdpr1=2.0*gfactor*rfactorrt*betaS[temp_kkp]
+                          *dBetaS[temp_ik]/rij[temp_ik];
+                      agpdpr2=2.0*gfactor*rfactorrt*betaS[temp_ik]
+                          *dBetaS[temp_kkp]/rij[temp_kkp];
+                      app1=rfactor*gfactorsq2*gsqprime;
+                      app2=rfactor*gfactorsq*gsqprime2;
+                      bt_sg[nb_ij].dCC[0]+=
+                          app1*dcAng[ang_jik][0][ngj];
+                      bt_sg[nb_ij].dCC[1]+=
+                          app1*dcAng[ang_jik][1][ngj];
+                      bt_sg[nb_ij].dCC[2]+=
+                          app1*dcAng[ang_jik][2][ngj];
+                      bt_sg[nb_ik].dCC[0]+=
+                          app1*dcAng[ang_jik][0][ngk]
+                          +agpdpr1*disij[0][temp_ik]
+                          -app2*dcAng[ang_ikkp][0][ngli];
+                      bt_sg[nb_ik].dCC[1]+=
+                          app1*dcAng[ang_jik][1][ngk]
+                          +agpdpr1*disij[1][temp_ik]
+                          -app2*dcAng[ang_ikkp][1][ngli];
+                      bt_sg[nb_ik].dCC[2]+=
+                          app1*dcAng[ang_jik][2][ngk]
+                          +agpdpr1*disij[2][temp_ik]
+                          -app2*dcAng[ang_ikkp][2][ngli];
+                      bt_sg[nb_kkp].dCC[0]+=
+                          app2*dcAng[ang_ikkp][0][nglkp]
+                          +agpdpr2*disij[0][temp_kkp];
+                      bt_sg[nb_kkp].dCC[1]+=
+                          app2*dcAng[ang_ikkp][1][nglkp]
+                          +agpdpr2*disij[1][temp_kkp];
+                      bt_sg[nb_kkp].dCC[2]+=
+                          app2*dcAng[ang_ikkp][2][nglkp]
+                          +agpdpr2*disij[2][temp_kkp];
+
+                    }
+                  }
+                }
+
+       //j and k are different neighbors of i and k' is a neighbor j not equal to k
+ 
+                kplist=firstneigh[kp];
+                for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+                  sig_flag=0;
+                  temp_jkp=BOP_index[j]+ltmp;
+                  if(neigh_flag[temp_jkp]) {
+                    kp=jlist[ltmp];
+                    kptype = map[type[kp]]+1;
+                    same_jkp=0;
+                    same_kkp=0;
+                    for(kpNeij=0;kpNeij<numneigh[kp];kpNeij++) {
+                      if(x[j][0]==x[kp][0]) {
+                        if(x[j][1]==x[kp][1]) {
+                          if(x[j][2]==x[kp][2]) {
+                            same_jkp=1;
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    for(kpNeik=0;kpNeik<numneigh[kp];kpNeik++) {
+                      if(x[k][0]==x[kp][0]) {
+                        if(x[k][1]==x[kp][1]) {
+                          if(x[k][2]==x[kp][2]) {
+                            same_kkp=1;
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    if(!same_kkp&&!same_jkp) {
+                      for(kNeikp=0;kNeikp<numneigh[k];kNeikp++) {
+                        temp_kkp=BOP_index[k]+kNeikp;
+                        kkp=klist[kNeikp];
+                        if(x[kkp][0]==x[kp][0]) {
+                          if(x[kkp][1]==x[kp][1]) {
+                            if(x[kkp][2]==x[kp][2]) {
+                              sig_flag=1;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==1) {
+                        for(nsearch=0;nsearch<numneigh[kp];nsearch++) {
+                          kp_nsearch=BOP_index[kp]+nsearch;
+                          ncmp=kplist[nsearch];
+                          if(x[ncmp][0]==x[j][0]) {
+                            if(x[ncmp][1]==x[j][1]) {
+                              if(x[ncmp][2]==x[j][2]) {
+                                kpNeij=nsearch;
+                              }
+                            }
+                          }
+                          if(x[ncmp][0]==x[k][0]) {
+                            if(x[ncmp][1]==x[k][1]) {
+                              if(x[ncmp][2]==x[k][2]) {
+                                kpNeik=nsearch;
+                              }
+                            }
+                          }
+                        }
+                        if(ji<ltmp) {
+                          nijkp=(ji)*numneigh[j]-(ji+1)*(ji+2)/2+ltmp;
+                          ngji=0;
+                          ngjkp=1;
+                        }
+                        else {
+                          nijkp=(ltmp)*numneigh[j]-(ltmp+1)*(ltmp+2)/2+ji;
+                          ngji=1;
+                          ngjkp=0;
+                        }
+                        if(kNeii<kNeikp) {
+                          nikkp=(kNeii)*numneigh[k]-(kNeii+1)*(kNeii+2)/2+kNeikp;
+                          ngki=0;
+                          ngkkp=1;
+                        }
+                        else {
+                          nikkp=(kNeikp)*numneigh[k]-(kNeikp+1)*(kNeikp+2)/2+kNeii;
+                          ngki=1;
+                          ngkkp=0;
+                        }
+                        if(kpNeij<kpNeik) {
+                          njkpk=(kpNeij)*numneigh[kp]-(kpNeij+1)*(kpNeij+2)/2+kpNeik;
+                          ngkpj=0;
+                          ngkpk=1;
+                        }
+                        else {
+                          njkpk=(kpNeik)*numneigh[kp]-(kpNeik+1)*(kpNeik+2)/2+kpNeij;
+                          ngkpj=1;
+                          ngkpk=0;
+                        }
+                        sig_flag=0;
+                        if(nSigBk[n]>neigh_ct) {
+                          printf("6 too big nSigBk\n");
+                          exit(1);
+                        }
+                        for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                          ncmp=itypeSigBk[n][nsearch];
+                          if(x[ncmp][0]==x[kp][0]) {
+                            if(x[ncmp][1]==x[kp][1]) {
+                              if(x[ncmp][2]==x[kp][2]) {
+                                nkp=nsearch;
+                                sig_flag=1;
+                                break;
+                              }
+                            }
+                          }
+                        }
+                        if(sig_flag==0) {
+                          nSigBk[n]=nSigBk[n]+1;
+                          nkp=nSigBk[n]-1;
+                          if(nkp>=neigh_ct) {
+                            printf("7 too big nSigBk\n");
+                            exit(1);
+                          }
+                          itypeSigBk[n][nkp]=kp;
+                        }
+                        ang_ijkp=cos_index[j]+nijkp;
+                        ang_ikkp=cos_index[k]+nikkp;
+                        ang_jkpk=cos_index[kp]+njkpk;
+                        nb_jkp=nb_t;
+                        nb_t++;
+                        if(nb_t>nb_sg) {
+                          new_n_tot=nb_sg+maxneigh;
+                          grow_sigma(nb_sg,new_n_tot);
+                          nb_sg=new_n_tot;
+                        }
+                        bt_sg[nb_jkp].temp=temp_jkp;
+                        bt_sg[nb_jkp].i=j;
+                        bt_sg[nb_jkp].j=kp;
+                        nb_kkp=nb_t;
+                        nb_t++;
+                        if(nb_t>nb_sg) {
+                          new_n_tot=nb_sg+maxneigh;
+                          grow_sigma(nb_sg,new_n_tot);
+                          nb_sg=new_n_tot;
+                        }
+                        bt_sg[nb_kkp].temp=temp_kkp;
+                        bt_sg[nb_kkp].i=k;
+                        bt_sg[nb_kkp].j=kp;
+                        gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+                        gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+                        gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+                        amean=cosAng[ang_ijkp];
+                        gfactor2=gmean0+gmean1*amean
+                            +gmean2*amean*amean;
+                        gprime2=gmean1+2.0*gmean2*amean;
+                        gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+                        gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+                        gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+                        amean=cosAng[ang_ikkp];
+                        gfactor3=gmean0+gmean1*amean
+                            +gmean2*amean*amean;
+                        gprime3=gmean1+2.0*gmean2*amean;
+                        gmean0=sigma_g0[jtype-1][kptype-1][ktype-1];
+                        gmean1=sigma_g1[jtype-1][kptype-1][ktype-1];
+                        gmean2=sigma_g2[jtype-1][kptype-1][ktype-1];
+                        amean=cosAng[ang_jkpk];
+                        gfactor4=gmean0+gmean1*amean
+                            +gmean2*amean*amean;
+                        gprime4=gmean1+2.0*gmean2*amean;
+                        gfactor=gfactor1*gfactor2*gfactor3*gfactor4;
+                        rfactor0=(betaS[temp_ik]+small2)*(betaS[temp_jkp]+small2)
+                            *(betaS[temp_kkp]+small2);
+                        rfactor=pow(rfactor0,2.0/3.0);
+                        drfactor=2.0/3.0*pow(rfactor0,-1.0/3.0);
+ 
+//EE is Eq. 25(notes)
+ 
+                        EE=EE+gfactor*rfactor;
+ 
+//agpdpr1 is derivative of agpdpr1 w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of agpdpr1 w.r.t. Beta(r_jk')
+//agpdpr3 is derivative of agpdpr1 w.r.t. Beta(r_kk')
+//app1 is derivative of agpdpr1 w.r.t. cos(theta_jik)
+//app2 is derivative of agpdpr1 w.r.t. cos(theta_ijk')
+//app3 is derivative of agpdpr1 w.r.t. cos(theta_ikk')
+//app4 is derivative of agpdpr1 w.r.t. cos(theta_jk'k)
+ 
+                        agpdpr1=gfactor*drfactor*(betaS[temp_jkp]+small2)*(betaS[temp_kkp]
+                            +small2)*dBetaS[temp_ik]/rij[temp_ik];
+                        agpdpr2=gfactor*drfactor*(betaS[temp_ik]+small2)*(betaS[temp_kkp]
+                            +small2)*dBetaS[temp_jkp]/rij[temp_jkp];
+                        agpdpr3=gfactor*drfactor*(betaS[temp_ik]+small2)*(betaS[temp_jkp]
+                            +small2)*dBetaS[temp_kkp]/rij[temp_kkp];
+                        app1=rfactor*gfactor2*gfactor3*gfactor4*gprime1;
+                        app2=rfactor*gfactor1*gfactor3*gfactor4*gprime2;
+                        app3=rfactor*gfactor1*gfactor2*gfactor4*gprime3;
+                        app4=rfactor*gfactor1*gfactor2*gfactor3*gprime4;
+                        bt_sg[nb_ij].dEE[0]+=
+                            app1*dcAng[ang_jik][0][ngj]
+                            -app2*dcAng[ang_ijkp][0][ngji];
+                        bt_sg[nb_ij].dEE[1]+=
+                            app1*dcAng[ang_jik][1][ngj]
+                            -app2*dcAng[ang_ijkp][1][ngji];
+                        bt_sg[nb_ij].dEE[2]+=
+                            app1*dcAng[ang_jik][2][ngj]
+                            -app2*dcAng[ang_ijkp][2][ngji];
+                        bt_sg[nb_ik].dEE[0]+=
+                            app1*dcAng[ang_jik][0][ngk]
+                            +agpdpr1*disij[0][temp_ik]
+                            -app3*dcAng[ang_ikkp][0][ngki];
+                        bt_sg[nb_ik].dEE[1]+=
+                            app1*dcAng[ang_jik][1][ngk]
+                            +agpdpr1*disij[1][temp_ik]
+                            -app3*dcAng[ang_ikkp][1][ngki];
+                        bt_sg[nb_ik].dEE[2]+=
+                            app1*dcAng[ang_jik][2][ngk]
+                            +agpdpr1*disij[2][temp_ik]
+                            -app3*dcAng[ang_ikkp][2][ngki];
+                        bt_sg[nb_jkp].dEE[0]+=
+                            app2*dcAng[ang_ijkp][0][ngjkp]
+                            +agpdpr2*disij[0][temp_jkp]
+                            -app4*dcAng[ang_jkpk][0][ngkpj];
+                        bt_sg[nb_jkp].dEE[1]+=
+                            app2*dcAng[ang_ijkp][1][ngjkp]
+                            +agpdpr2*disij[1][temp_jkp]
+                            -app4*dcAng[ang_jkpk][1][ngkpj];
+                        bt_sg[nb_jkp].dEE[2]+=
+                            app2*dcAng[ang_ijkp][2][ngjkp]
+                            +agpdpr2*disij[2][temp_jkp]
+                            -app4*dcAng[ang_jkpk][2][ngkpj];
+                        bt_sg[nb_kkp].dEE[0]+=
+                            app3*dcAng[ang_ikkp][0][ngkkp]
+                            +agpdpr3*disij[0][temp_kkp]
+                            -app4*dcAng[ang_jkpk][0][ngkpk];
+                        bt_sg[nb_kkp].dEE[1]+=
+                            app3*dcAng[ang_ikkp][1][ngkkp]
+                            +agpdpr3*disij[1][temp_kkp]
+                            -app4*dcAng[ang_jkpk][1][ngkpk];
+                        bt_sg[nb_kkp].dEE[2]+=
+                            app3*dcAng[ang_ikkp][2][ngkkp]
+                            +agpdpr3*disij[2][temp_kkp]
+                            -app4*dcAng[ang_jkpk][2][ngkpk];
+                      }
+                    }
+                  }
+                }
+              }
+            }
+          }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+          for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+            if(ktmp!=ji) {
+              if(ktmp<ji) {
+                njik=ktmp*(2*numneigh[j]-ktmp-1)/2+(ji-ktmp)-1;
+                ngi=1;
+                ngk=0;
+              }
+              else {
+                njik=ji*(2*numneigh[j]-ji-1)/2+(ktmp-ji)-1;
+                ngi=0;
+                ngk=1;
+              }
+              temp_jk=BOP_index[j]+ktmp;
+              if(neigh_flag[temp_jk]) {
+                k=jlist[ktmp];
+                ktype=map[type[k]]+1;
+                klist=firstneigh[k];
+
+                for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                  if(x[klist[kNeij]][0]==x[j][0]) {
+                    if(x[klist[kNeij]][1]==x[j][1]) {
+                      if(x[klist[kNeij]][2]==x[j][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+                sig_flag=0;
+                if(nSigBk[n]>neigh_ct) {
+                  printf("8 too big nSigBk\n");
+                  exit(1);
+                }
+                for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                  ncmp=itypeSigBk[n][nsearch];
+                  if(x[ncmp][0]==x[k][0]) {
+                    if(x[ncmp][1]==x[k][1]) {
+                      if(x[ncmp][2]==x[k][2]) {
+                        new1=nsearch;
+                        sig_flag=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(sig_flag==0) {
+                  nSigBk[n]=nSigBk[n]+1;
+                  new1=nSigBk[n]-1;
+                  if(new1>=neigh_ct) {
+                    printf("9 too big nSigBk\n");
+                    exit(1);
+                  }
+                  itypeSigBk[n][new1]=k;
+                }
+                ang_ijk=cos_index[j]+njik;
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                amean=cosAng[ang_ijk];
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gsqprime=2.0*gfactor1*gprime1;
+                rfactor1rt=betaS[temp_jk]*betaS[temp_jk];
+                rfactor1=rfactor1rt*rfactor1rt;
+
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+
+                BB=BB+gfactorsq*rfactor1rt;
+                DD=DD+gfactorsq*rfactor1;
+
+//agpdpr1 is derivative of BB  w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+
+                agpdpr1=2.0*gfactorsq*betaS[temp_jk]*dBetaS[temp_jk]/rij[temp_jk];
+                app1=rfactor1rt*gsqprime;
+                bt_sg[nb_ij].dBB[0]-=
+                    app1*dcAng[ang_ijk][0][ngi];
+                bt_sg[nb_ij].dBB[1]-=
+                    app1*dcAng[ang_ijk][1][ngi];
+                bt_sg[nb_ij].dBB[2]-=
+                    app1*dcAng[ang_ijk][2][ngi];
+                bt_sg[nb_ij].dDD[0]-=
+                    app2*dcAng[ang_ijk][0][ngi];
+                bt_sg[nb_ij].dDD[1]-=
+                    app2*dcAng[ang_ijk][1][ngi];
+                bt_sg[nb_ij].dDD[2]-=
+                    app2*dcAng[ang_ijk][2][ngi];
+                bt_sg[nb_jk].dBB[0]+=
+                    app1*dcAng[ang_ijk][0][ngk]
+                    +agpdpr1*disij[0][temp_jk];
+                bt_sg[nb_jk].dBB[1]+=
+                    app1*dcAng[ang_ijk][1][ngk]
+                    +agpdpr1*disij[1][temp_jk];
+                bt_sg[nb_jk].dBB[2]+=
+                    app1*dcAng[ang_ijk][2][ngk]
+                    +agpdpr1*disij[2][temp_jk];
+                bt_sg[nb_jk].dDD[0]+=
+                    app2*dcAng[ang_ijk][0][ngk]
+                    +agpdpr2*disij[0][temp_jk];
+                bt_sg[nb_jk].dDD[1]+=
+                    app2*dcAng[ang_ijk][1][ngk]
+                    +agpdpr2*disij[1][temp_jk];
+                bt_sg[nb_jk].dDD[2]+=
+                    app2*dcAng[ang_ijk][2][ngk]
+                    +agpdpr2*disij[2][temp_jk];
+
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=ji) {
+                    temp_jkp=BOP_index[j]+ltmp;
+                    if(neigh_flag[temp_jkp]) {
+                      kp=jlist[ltmp];
+                      kptype=map[type[kp]]+1;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("10 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              new2=nsearch;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(ji<ltmp) {
+                        nijkp=ji*(2*numneigh[j]-ji-1)/2+(ltmp-ji)-1;
+                        ngli=0;
+                        ngl=1;
+                      }
+                      else {
+                        nijkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ji-ltmp)-1;
+                        ngli=1;
+                        ngl=0;
+                      }
+                      if(ktmp<ltmp) {
+                        nkjkp=ktmp*(2*numneigh[j]-ktmp-1)/2+(ltmp-ktmp)-1;
+                        ngjk=0;
+                        ngjkp=1;
+                      }
+                      else {
+                        nkjkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ktmp-ltmp)-1;
+                        ngjk=1;
+                        ngjkp=0;
+                      }
+                      ang_ijkp=cos_index[j]+nijkp;
+                      ang_kjkp=cos_index[j]+nkjkp;
+                      gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+                      amean=cosAng[ang_ijkp];
+                      gfactor2=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+                      amean=cosAng[ang_kjkp];
+                      gfactor3=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS[temp_jk]*betaS[temp_jkp];
+                      rfactor=rfactorrt*rfactorrt;
+
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+
+                      DD=DD+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of DD  w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD  w.r.t. Beta(r_jk')
+//app1 is derivative of DD  w.r.t. cos(theta_ijk)
+//app2 is derivative of DD  w.r.t. cos(theta_ijkp)
+//app3 is derivative of DD  w.r.t. cos(theta_kjkp)
+ 
+                      agpdpr1=4.0*gfactor*rfactorrt*betaS[temp_jkp]
+                          *dBetaS[temp_jk]/rij[temp_jk];
+                          agpdpr2=4.0*gfactor*rfactorrt*betaS[temp_jk]
+                          *dBetaS[temp_jkp]/rij[temp_jkp];
+                      app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+                      app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+                      app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+                      bt_sg[nb_ij].dDD[0]-=
+                          app1*dcAng[ang_ijk][0][ngi]
+                          +app2*dcAng[ang_ijkp][0][ngli];
+                      bt_sg[nb_ij].dDD[1]-=
+                          app1*dcAng[ang_ijk][1][ngi]
+                          +app2*dcAng[ang_ijkp][1][ngli];
+                      bt_sg[nb_ij].dDD[2]-=
+                          app1*dcAng[ang_ijk][2][ngi]
+                          +app2*dcAng[ang_ijkp][2][ngli];
+                      bt_sg[nb_jk].dDD[0]+=
+                          app1*dcAng[ang_ijk][0][ngk]
+                          +app3*dcAng[ang_kjkp][0][ngjk]
+                          +agpdpr1*disij[0][temp_jk];
+                      bt_sg[nb_jk].dDD[1]+=
+                          app1*dcAng[ang_ijk][1][ngk]
+                          +app3*dcAng[ang_kjkp][1][ngjk]
+                          +agpdpr1*disij[1][temp_jk];
+                      bt_sg[nb_jk].dDD[2]+=
+                          app1*dcAng[ang_ijk][2][ngk]
+                          +app3*dcAng[ang_kjkp][2][ngjk]
+                          +agpdpr1*disij[2][temp_jk];
+                      bt_sg[nb_jkp].dDD[0]+=
+                          app2*dcAng[ang_ijkp][0][ngl]
+                          +app3*dcAng[ang_kjkp][0][ngjkp]
+                          +agpdpr2*disij[0][temp_jkp];
+                      bt_sg[nb_jkp].dDD[1]+=
+                          app2*dcAng[ang_ijkp][1][ngl]
+                          +app3*dcAng[ang_kjkp][1][ngjkp]
+                          +agpdpr2*disij[1][temp_jkp];
+                      bt_sg[nb_jkp].dDD[2]+=
+                          app2*dcAng[ang_ijkp][2][ngl]
+                          +app3*dcAng[ang_kjkp][2][ngjkp]
+                          +agpdpr2*disij[2][temp_jkp];
+                    }
+                  }
+                }
+
+//j is a neighbor of i, k is a neighbor of j not equal to i and k' 
+//is a neighbor of k not equal to j or i
+
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  if(neigh_flag[temp_kkp]) {
+                    kp=klist[ltmp];
+                    kptype=map[type[kp]]+1;
+                    same_ikp=0;
+                    same_jkp=0;
+                    if(x[i][0]==x[kp][0]) {
+                      if(x[i][1]==x[kp][1]) {
+                        if(x[i][2]==x[kp][2]) {
+                          same_ikp=1;
+                        }
+                      }
+                    }
+                    if(x[j][0]==x[kp][0]) {
+                      if(x[j][1]==x[kp][1]) {
+                        if(x[j][2]==x[kp][2]) {
+                          same_jkp=1;
+                        }
+                      }
+                    }
+                    if(!same_ikp&&!same_jkp) {
+                      for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                        if(x[klist[kNeij]][0]==x[j][0]) {
+                          if(x[klist[kNeij]][1]==x[j][1]) {
+                            if(x[klist[kNeij]][2]==x[j][2]) {
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(kNeij<ltmp) {
+                        njkkp=kNeij*(2*numneigh[k]-kNeij-1)/2+(ltmp-kNeij)-1;
+                        nglkp=1;
+                        nglj=0;
+                      }
+                      else {
+                        njkkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeij-ltmp)-1;
+                        nglkp=0;
+                        nglj=1;
+                      }
+                      sig_flag=0;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("11 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              new2=nsearch;
+                              sig_flag=1;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==0) {
+                        nSigBk[n]=nSigBk[n]+1;
+                        new2=nSigBk[n]-1;
+                        if(new2>=neigh_ct) {
+                          printf("12 too big nSigBk\n");
+                          exit(1);
+                        }
+                        itypeSigBk[n][new2]=kp;
+                      }
+                      ang_jkkp=cos_index[k]+njkkp;
+                      nb_kkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_kkp].temp=temp_kkp;
+                      bt_sg[nb_kkp].i=k;
+                      bt_sg[nb_kkp].j=kp;
+                      gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+                      amean=cosAng[ang_jkkp];
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS[temp_jk]*betaS[temp_kkp];
+                      rfactor=rfactorrt*rfactorrt;
+
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+
+                      DD=DD+gfactor*rfactor;
+
+//agpdpr1 is derivative of DD  3rd term w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD  3rd term w.r.t. Beta(r_kk')
+//app1 is derivative of DD  3rd term w.r.t. cos(theta_ijk)
+//app2 is derivative of DD  3rd term w.r.t. cos(theta_jkkp)
+ 
+                      agpdpr1=2.0*gfactor*rfactorrt*betaS[temp_kkp]
+                          *dBetaS[temp_jk]/rij[temp_jk];
+                      agpdpr2=2.0*gfactor*rfactorrt*betaS[temp_jk]
+                          *dBetaS[temp_kkp]/rij[temp_kkp];
+                      app1=rfactor*gfactorsq2*gsqprime;
+                      app2=rfactor*gfactorsq*gsqprime2;
+                      bt_sg[nb_ij].dDD[0]-=
+                          app1*dcAng[ang_ijk][0][ngi];
+                      bt_sg[nb_ij].dDD[1]-=
+                          app1*dcAng[ang_ijk][1][ngi];
+                      bt_sg[nb_ij].dDD[2]-=
+                          app1*dcAng[ang_ijk][2][ngi];
+                      bt_sg[nb_jk].dDD[0]+=
+                          app1*dcAng[ang_ijk][0][ngk]
+                          +agpdpr1*disij[0][temp_jk]
+                          -app2*dcAng[ang_jkkp][0][nglj];
+                      bt_sg[nb_jk].dDD[1]+=
+                          app1*dcAng[ang_ijk][1][ngk]
+                          +agpdpr1*disij[1][temp_jk]
+                          -app2*dcAng[ang_jkkp][1][nglj];
+                      bt_sg[nb_jk].dDD[2]+=
+                          app1*dcAng[ang_ijk][2][ngk]
+                          +agpdpr1*disij[2][temp_jk]
+                          -app2*dcAng[ang_jkkp][2][nglj];
+                      bt_sg[nb_kkp].dDD[0]+=
+                          app2*dcAng[ang_jkkp][0][nglkp]
+                          +agpdpr2*disij[0][temp_kkp];
+                      bt_sg[nb_kkp].dDD[1]+=
+                          app2*dcAng[ang_jkkp][1][nglkp]
+                          +agpdpr2*disij[1][temp_kkp];
+                      bt_sg[nb_kkp].dDD[2]+=
+                          app2*dcAng[ang_jkkp][2][nglkp]
+                          +agpdpr2*disij[2][temp_kkp];
+                    }
+                  }
+                }
+              }
+            }
+          }
+
+          sig_flag=0;
+          if(FF<=0.000001) {
+            sigB[n]=0.0;
+            sig_flag=1;
+          }
+          if(sig_flag==0) {
+            if(AA<0.0)
+              AA=0.0;
+            if(BB<0.0)
+              BB=0.0;
+            if(CC<0.0)
+              CC=0.0;
+            if(DD<0.0)
+              DD=0.0;
+
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+
+            AAC=AA+BB;
+            BBC=AA*BB;
+            CCC=AA*AA+BB*BB;
+            DDC=CC+DD;
+
+//EEC is a modified form of (a) Eq. 33
+
+            EEC=(DDC-CCC)/(AAC+2.0*small1);
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                bt_i=bt_sg[m].i;
+                bt_j=bt_sg[m].j;
+                bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+                    +bt_sg[m].dBB[0];
+                bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+                    +bt_sg[m].dBB[1];
+                bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+                    +bt_sg[m].dBB[2];
+                bt_sg[m].dBBC[0]=bt_sg[m].dAA[0]*BB
+                    +AA*bt_sg[m].dBB[0];
+                bt_sg[m].dBBC[1]=bt_sg[m].dAA[1]*BB
+                    +AA*bt_sg[m].dBB[1];
+                bt_sg[m].dBBC[2]=bt_sg[m].dAA[2]*BB
+                    +AA*bt_sg[m].dBB[2];
+                bt_sg[m].dCCC[0]=2.0*AA*bt_sg[m].dAA[0]
+                    +2.0*BB*bt_sg[m].dBB[0];
+                bt_sg[m].dCCC[1]=2.0*AA*bt_sg[m].dAA[1]
+                    +2.0*BB*bt_sg[m].dBB[1];
+                bt_sg[m].dCCC[2]=2.0*AA*bt_sg[m].dAA[2]
+                    +2.0*BB*bt_sg[m].dBB[2];
+                bt_sg[m].dDDC[0]=bt_sg[m].dCC[0]
+                    +bt_sg[m].dDD[0];
+                bt_sg[m].dDDC[1]=bt_sg[m].dCC[1]
+                    +bt_sg[m].dDD[1];
+                bt_sg[m].dDDC[2]=bt_sg[m].dCC[2]
+                    +bt_sg[m].dDD[2];
+                bt_sg[m].dEEC[0]=(bt_sg[m].dDDC[0]
+                    -bt_sg[m].dCCC[0]
+                    -EEC*bt_sg[m].dAAC[0])*AACFF;
+                bt_sg[m].dEEC[1]=(bt_sg[m].dDDC[1]
+                    -bt_sg[m].dCCC[1]
+                    -EEC*bt_sg[m].dAAC[1])*AACFF;
+                bt_sg[m].dEEC[2]=(bt_sg[m].dDDC[2]
+                    -bt_sg[m].dCCC[2]
+                    -EEC*bt_sg[m].dAAC[2])*AACFF;
+              } 
+            }
+            UT=EEC*FF+BBC+small3[iij];
+            UT=1.0/sqrt(UT);
+
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+
+            FFC=BBC*UT;
+            GGC=EEC*UT;
+            bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])
+                +sigma_c[iij]*AAC+small4;
+            UTcom=-0.5*UT*UT*UT;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                bt_sg[m].dUT[0]=UTcom*(bt_sg[m].dEEC[0]*FF
+                    +EEC*bt_sg[m].dFF[0]+bt_sg[m].dBBC[0]);
+                bt_sg[m].dUT[1]=UTcom*(bt_sg[m].dEEC[1]*FF
+                    +EEC*bt_sg[m].dFF[1]+bt_sg[m].dBBC[1]);
+                bt_sg[m].dUT[2]=UTcom*(bt_sg[m].dEEC[2]*FF
+                    +EEC*bt_sg[m].dFF[2]+bt_sg[m].dBBC[2]);
+                bt_sg[m].dFFC[0]=bt_sg[m].dBBC[0]*UT
+                    +BBC*bt_sg[m].dUT[0];
+                bt_sg[m].dFFC[1]=bt_sg[m].dBBC[1]*UT
+                    +BBC*bt_sg[m].dUT[1];
+                bt_sg[m].dFFC[2]=bt_sg[m].dBBC[2]*UT
+                    +BBC*bt_sg[m].dUT[2];
+                bt_sg[m].dGGC[0]=bt_sg[m].dEEC[0]*UT
+                    +EEC*bt_sg[m].dUT[0];
+                bt_sg[m].dGGC[1]=bt_sg[m].dEEC[1]*UT
+                    +EEC*bt_sg[m].dUT[1];
+                bt_sg[m].dGGC[2]=bt_sg[m].dEEC[2]*UT
+                    +EEC*bt_sg[m].dUT[2];
+              }
+            }
+            psign=1.0;
+            if(1.0+sigma_a[iij]*GGC<0.0)
+              psign=-1.0;
+            bndtmp0=1.0/sqrtl(bndtmp);
+            sigB1[n]=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)*bndtmp0;
+            bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+            bndtmp1=psign*(1.0+sigma_a[iij]*GGC)*bndtmp0+psign*betaS[temp_ij]
+                *(1.0+sigma_a[iij]*GGC)*bndtmp*2.0*betaS[temp_ij]*(1.0
+                +sigma_a[iij]*GGC)*(1.0+sigma_a[iij]*GGC);
+            bndtmp1=bndtmp1*dBetaS[temp_ij]/rij[temp_ij];
+            bndtmp2=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)*bndtmp*sigma_c[iij];
+            bndtmp3=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)
+                *bndtmp*sigma_c[iij]*sigma_a[iij];
+            bndtmp4=psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)
+                *bndtmp*sigma_c[iij]*sigma_a[iij]*(2.0+GGC);
+            bndtmp5=sigma_a[iij]*psign*betaS[temp_ij]*bndtmp0
+                +psign*betaS[temp_ij]*(1.0+sigma_a[iij]*GGC)*bndtmp
+                *(2.0*(FF+sigma_delta[iij]*sigma_delta[iij])*(1.0
+                +sigma_a[iij]*GGC)*sigma_a[iij]+sigma_c[iij]*sigma_a[iij]*FFC);
+            setting=0;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                if(temp_kk==temp_ij&&setting==0) {
+                  bt_sg[m].dSigB1[0]=bndtmp1*disij[0][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[0]
+                      +bndtmp3*bt_sg[m].dEE[0]
+                      +bndtmp4*bt_sg[m].dFFC[0]
+                      +bndtmp5*bt_sg[m].dGGC[0]);
+                  bt_sg[m].dSigB1[1]=bndtmp1*disij[1][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[1]
+                      +bndtmp3*bt_sg[m].dEE[1]
+                      +bndtmp4*bt_sg[m].dFFC[1]
+                      +bndtmp5*bt_sg[m].dGGC[1]);
+                  bt_sg[m].dSigB1[2]=bndtmp1*disij[2][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[2]
+                      +bndtmp3*bt_sg[m].dEE[2]
+                      +bndtmp4*bt_sg[m].dFFC[2]
+                      +bndtmp5*bt_sg[m].dGGC[2]);
+                  setting=1;
+                }
+                else if(temp_kk==temp_ji&&setting==0) {
+                  bt_sg[m].dSigB1[0]=-bndtmp1*disij[0][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[0]
+                      +bndtmp3*bt_sg[m].dEE[0]
+                      +bndtmp4*bt_sg[m].dFFC[0]
+                      +bndtmp5*bt_sg[m].dGGC[0]);
+                  bt_sg[m].dSigB1[1]=-bndtmp1*disij[1][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[1]
+                      +bndtmp3*bt_sg[m].dEE[1]
+                      +bndtmp4*bt_sg[m].dFFC[1]
+                      +bndtmp5*bt_sg[m].dGGC[1]);
+                  bt_sg[m].dSigB1[2]=-bndtmp1*disij[2][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[2]
+                      +bndtmp3*bt_sg[m].dEE[2]
+                      +bndtmp4*bt_sg[m].dFFC[2]
+                      +bndtmp5*bt_sg[m].dGGC[2]);
+                  setting=1;
+                }
+                else {
+                  bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]
+                      +bndtmp3*bt_sg[m].dEE[0]
+                      +bndtmp4*bt_sg[m].dFFC[0]
+                      +bndtmp5*bt_sg[m].dGGC[0]);
+                  bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]
+                      +bndtmp3*bt_sg[m].dEE[1]
+                      +bndtmp4*bt_sg[m].dFFC[1]
+                      +bndtmp5*bt_sg[m].dGGC[1]);
+                  bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]
+                      +bndtmp3*bt_sg[m].dEE[2]
+                      +bndtmp4*bt_sg[m].dFFC[2]
+                      +bndtmp5*bt_sg[m].dGGC[2]);
+                }
+              }
+            }
+
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+
+            if(nb_t==0) {
+              if(j>i) {
+                bt_sg[0].dSigB1[0]=bndtmp1*disij[0][temp_ij];
+                bt_sg[0].dSigB1[1]=bndtmp1*disij[1][temp_ij];
+                bt_sg[0].dSigB1[2]=bndtmp1*disij[2][temp_ij];
+              }
+              else {
+                bt_sg[0].dSigB1[0]=-bndtmp1*disij[0][temp_ij];
+                bt_sg[0].dSigB1[1]=-bndtmp1*disij[1][temp_ij];
+                bt_sg[0].dSigB1[2]=-bndtmp1*disij[2][temp_ij];
+              }
+              for(pp=0;pp<3;pp++) {
+                bt_sg[0].dAA[pp]=0.0;
+                bt_sg[0].dBB[pp]=0.0;
+                bt_sg[0].dCC[pp]=0.0;
+                bt_sg[0].dDD[pp]=0.0;
+                bt_sg[0].dEE[pp]=0.0;
+                bt_sg[0].dEE1[pp]=0.0;
+                bt_sg[0].dFF[pp]=0.0;
+                bt_sg[0].dAAC[pp]=0.0;
+                bt_sg[0].dBBC[pp]=0.0;
+                bt_sg[0].dCCC[pp]=0.0;
+                bt_sg[0].dDDC[pp]=0.0;
+                bt_sg[0].dEEC[pp]=0.0;
+                bt_sg[0].dFFC[pp]=0.0;
+                bt_sg[0].dGGC[pp]=0.0;
+                bt_sg[0].dUT[pp]=0.0;
+                bt_sg[0].dSigB1[pp]=0.0;
+                bt_sg[0].dSigB[pp]=0.0;
+              }
+              bt_sg[0].i=i;
+              bt_sg[0].j=j;
+              bt_sg[0].temp=temp_ij;
+              nb_t++;
+              if(nb_t>nb_sg) {
+                new_n_tot=nb_sg+maxneigh;
+                grow_sigma(nb_sg,new_n_tot);
+                nb_sg=new_n_tot;
+              }
+            }
+            ps=sigB1[n]*rdBO+1.0;
+            ks=(int)ps;
+            if(nBOt-1<ks)
+              ks=nBOt-1;
+            ps=ps-ks;
+            if(ps>1.0)
+              ps=1.0;
+            dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+                +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+            dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+            part0=(FF+0.5*AAC+small5);
+            part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+            part2=1.0-part1*EE1/part0;
+            part3=dsigB1*part1/part0;
+            part4=part3/part0*EE1;
+
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+
+            sigB[n]=dsigB1*part2;
+            pp1=2.0*betaS[temp_ij];
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                bt_ij=bt_sg[m].temp;
+                bt_i=bt_sg[m].i;
+                bt_j=bt_sg[m].j;
+                for(pp=0;pp<3;pp++) {
+                  bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+                      -part3*bt_sg[m].dEE1[pp]
+                      +part4*(bt_sg[m].dFF[pp]
+                      +0.5*bt_sg[m].dAAC[pp]);
+                }
+                for(pp=0;pp<3;pp++) {
+                  ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+                  f[bt_i][pp]-=ftmp[pp];
+                  f[bt_j][pp]+=ftmp[pp];
+                }
+                if(evflag) {
+                  ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                      ,ftmp[2],disij[0][bt_ij],disij[1][bt_ij],disij[2][bt_ij]);
+                }
+              }
+            }
+          }
+          n++;
+        }
+      }
+    }
+  }
+  if(allocate_sigma)
+    destroy_sigma();
+}
+
+void PairBOP::sigmaBo_noa()
+{
+  int nb_t,new_n_tot;
+  int n,i,j,k,kp,m,pp;
+  int iij,ji,ki;
+  int itmp,jtmp,ktmp,ltmp,mtmp;
+  int i_tag,j_tag;
+  int ngi,ngj,ngk,ngli,nglj,ngl;
+  int ngji,ngjk,nikj,ngki,ngkj;
+  int njik,nijk,nikkp,nkp,nijkp;
+  int nkikp,njikp,nk0,nkjkp,njkkp;
+  int jNeik,kNeii,kNeij;
+  int new1,new2,nlocal,nsearch;
+  int inum,*ilist,*iilist,*jlist,*klist;
+  int **firstneigh,*numneigh;
+  int temp_ji,temp_ikp,temp_ki,temp_kkp;
+  int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+  int ang_ijkp,ang_ikkp,ang_kjkp;
+  int ang_ijk,ang_ikj,ang_jikp,ang_jkkp;
+  int ang_jik,ang_kikp;
+  int nb_ij,nb_ik,nb_jk;
+  int sig_flag,setting,ncmp,ks;
+  int itype,jtype,ktype,kptype;
+  int bt_i,bt_j,bt_ij;
+  int kp_index,same_ikp,same_jkp;
+  double AA,BB,CC,DD,EE,EE1,FF;
+  double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+  double AACFF,UT,bndtmp,UTcom;
+  double amean,gmean0,gmean1,gmean2,ps;
+  double gfactor1,gprime1,gsqprime,factorsq;
+  double gfactorsq,gfactor2,gprime2;
+  double gfactorsq2,gsqprime2;
+  double gfactor3,gprime3,gfactor,rfactor;
+  double drfactor,gfactor4,gprime4,agpdpr3;
+  double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+  double rcm1,rcm2,gcm1,gcm2,gcm3;
+  double agpdpr1,agpdpr2,app1,app2,app3,app4;
+  double dsigB1,dsigB2;
+  double part0,part1,part2,part3,part4;
+  double psign,bndtmp0,pp1,bndtmp1,bndtmp2;
+  double ftmp[3];
+  double **x = atom->x;
+  double **f = atom->f;
+  int *tag = atom->tag;
+  int newton_pair = force->newton_pair;
+  int *type = atom->type;
+ 
+  nlocal = atom->nlocal;
+  int nall = nlocal+atom->nghost;
+  firstneigh = list->firstneigh;
+  numneigh = list->numneigh;
+  inum = list->inum; 
+  ilist = list->ilist;
+  n=0;
+ 
+//loop over all local atoms
+
+  if(nb_sg>16) {
+    nb_sg=16;
+  }
+  if(nb_sg==0) {
+    nb_sg=(maxneigh)*(maxneigh/2);
+  }
+  if(allocate_sigma) {
+    destroy_sigma();
+  }
+  create_sigma(nb_sg);
+  for(itmp=0;itmp<inum;itmp++) {
+    i = ilist[itmp];
+    i_tag=tag[i];  
+    itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+
+    for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+      temp_ij=BOP_index[i]+jtmp;
+      if(neigh_flag[temp_ij]) {
+        for(m=0;m<nb_sg;m++) {
+          for(pp=0;pp<3;pp++) {
+            bt_sg[m].dAA[pp]=0.0;
+            bt_sg[m].dBB[pp]=0.0;
+            bt_sg[m].dEE1[pp]=0.0;
+            bt_sg[m].dFF[pp]=0.0;
+            bt_sg[m].dAAC[pp]=0.0;
+            bt_sg[m].dSigB1[pp]=0.0;
+            bt_sg[m].dSigB[pp]=0.0;
+          }
+          bt_sg[m].i=-1;
+          bt_sg[m].j=-1;
+        }
+        nb_t=0;
+        iilist=firstneigh[i];
+        j=iilist[jtmp];
+        jlist=firstneigh[j];
+        for(ki=0;ki<numneigh[j];ki++) {
+          temp_ki=BOP_index[j]+ki;
+          if(x[jlist[ki]][0]==x[i][0]) {
+            if(x[jlist[ki]][1]==x[i][1]) {
+              if(x[jlist[ki]][2]==x[i][2]) {
+                if(!neigh_flag[temp_ki]) {
+                  printf("BOP 10:error 1 flag %7d temp %7d %7d\n",neigh_flag[temp_ki],temp_ki,temp_ij)
+;
+                  exit(1);
+                }
+                break;
+              }
+            }
+          }
+        } 
+        j_tag=tag[j];
+        jtype = map[type[j]]+1;
+        nb_ij=nb_t;
+        nb_t++;
+        if(nb_t>nb_sg) {
+          new_n_tot=nb_sg+maxneigh;
+          grow_sigma(nb_sg,new_n_tot);
+          nb_sg=new_n_tot;
+        }
+        bt_sg[nb_ij].temp=temp_ij;
+        bt_sg[nb_ij].i=i;
+        bt_sg[nb_ij].j=j;
+        if(j_tag>=i_tag) {
+          if(n>=neigh_total) {
+            printf("BOP 12:n is too large \n");
+            exit(1);
+          }
+          if(itype==jtype)
+            iij=itype-1;
+          else if(itype<jtype)
+            iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+          else
+            iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+          for(ji=0;ji<numneigh[j];ji++) {
+            temp_ji=BOP_index[j]+ji;
+            if(x[jlist[ji]][0]==x[i][0]) {
+              if(x[jlist[ji]][1]==x[i][1]) {
+                if(x[jlist[ji]][2]==x[i][2]) {
+                  break;
+                }
+              }
+            }
+          }
+          nSigBk[n]=0;
+ 
+//AA-EE1 are the components making up Eq. 30 (a)
+ 
+          AA=0.0;
+          BB=0.0;
+          CC=0.0;
+          DD=0.0;
+          EE1=0.0;
+ 
+//FF is the Beta_sigma^2 term
+       
+          FF=betaS[temp_ij]*betaS[temp_ij];
+ 
+//agpdpr1 is derivative of FF w.r.t. r_ij
+ 
+          agpdpr1=2.0*betaS[temp_ij]*dBetaS[temp_ij]/rij[temp_ij];
+ 
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+ 
+          bt_sg[nb_ij].dFF[0]=agpdpr1*disij[0][temp_ij];
+          bt_sg[nb_ij].dFF[1]=agpdpr1*disij[1][temp_ij];
+          bt_sg[nb_ij].dFF[2]=agpdpr1*disij[2][temp_ij];
+ 
+//k is loop over all neighbors of i again with j neighbor of i 
+          for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+            temp_ik=BOP_index[i]+ktmp;       
+            if(neigh_flag[temp_ik]) {
+              if(ktmp!=jtmp) {
+                if(jtmp<ktmp) {
+                  njik=jtmp*(2*numneigh[i]-jtmp-1)/2+(ktmp-jtmp)-1;
+                  ngj=0;
+                  ngk=1;
+                }
+                else {
+                  njik=ktmp*(2*numneigh[i]-ktmp-1)/2+(jtmp-ktmp)-1;
+                  ngj=1;
+                  ngk=0;
+                }
+                k=iilist[ktmp];
+                ktype = map[type[k]]+1;
+ 
+//find neighbor of k that is equal to i
+ 
+                klist=firstneigh[k];
+                for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+                  temp_ki=BOP_index[k]+kNeii;
+                  if(x[klist[kNeii]][0]==x[i][0]) {
+                    if(x[klist[kNeii]][1]==x[i][1]) {
+                      if(x[klist[kNeii]][2]==x[i][2]) {
+                        if(!neigh_flag[temp_ki]) {
+                          printf("BOP 11:error 2 flag %7d temp %7d %7d\n",neigh_flag[temp_ki],temp_ki,temp_ij);
+                          exit(1);
+                        }
+                        break;
+                      }
+                    }
+                  }
+                }
+ 
+//find neighbor of i that is equal to k
+ 
+                for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+                  temp_jk=BOP_index[j]+jNeik;
+                  if(x[jlist[jNeik]][0]==x[k][0]) {
+                    if(x[jlist[jNeik]][1]==x[k][1]) {
+                      if(x[jlist[jNeik]][2]==x[k][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+ 
+//find neighbor of k that is equal to j
+ 
+                for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                  if(x[klist[kNeij]][0]==x[j][0]) {
+                    if(x[klist[kNeij]][1]==x[j][1]) {
+                      if(x[klist[kNeij]][2]==x[j][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+                sig_flag=0;
+                if(nSigBk[n]>neigh_ct) {
+                  printf("13 too big nSigBk\n");
+                  exit(1);
+                }
+                for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                  ncmp=itypeSigBk[n][nsearch];
+                  if(x[ncmp][0]==x[k][0]) {
+                    if(x[ncmp][1]==x[k][1]) {
+                      if(x[ncmp][2]==x[k][2]) {
+                        nk0=nsearch;
+                        sig_flag=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(sig_flag==0) {
+                  nSigBk[n]=nSigBk[n]+1;
+                  nk0=nSigBk[n]-1;
+                  if(nk0>=neigh_ct) {
+                    printf("14 too big nSigBk\n");
+                    exit(1);
+                  }
+                  itypeSigBk[n][nk0]=k;
+                }
+                nb_ik=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_ik].temp=temp_ik;
+                bt_sg[nb_ik].i=i;
+                bt_sg[nb_ik].j=k;
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                ang_jik=cos_index[i]+njik;
+                if(ang_jik>=cos_total) {
+                  printf("1 error in cos %7d\n",ang_jik);
+                  exit(1);
+                }
+                gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+                gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+                gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+                amean=cosAng[ang_jik];
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gsqprime=2.0*gfactor1*gprime1;
+ 
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+ 
+                AA=AA+gfactorsq*betaS[temp_ik]*betaS[temp_ik];
+                CC=CC+gfactorsq*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik]*betaS[temp_ik];
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//agpdpr2 is derivative of CC 1st term w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+//app2 is derivative of CC 1st term w.r.t. cos(theta_jik)
+ 
+                agpdpr1=2.0*gfactorsq*betaS[temp_ik]*dBetaS[temp_ik]/rij[temp_ik];
+                app1=betaS[temp_ik]*betaS[temp_ik]*gsqprime;
+                bt_sg[nb_ij].dAA[0]+=
+                    app1*dcAng[ang_jik][0][ngj];
+                bt_sg[nb_ij].dAA[1]+=
+                    app1*dcAng[ang_jik][1][ngj];
+                bt_sg[nb_ij].dAA[2]+=
+                    app1*dcAng[ang_jik][2][ngj];
+                bt_sg[nb_ik].dAA[0]+=
+                    app1*dcAng[ang_jik][0][ngk]
+                    +agpdpr1*disij[0][temp_ik];
+                bt_sg[nb_ik].dAA[1]+=
+                    app1*dcAng[ang_jik][1][ngk]
+                    +agpdpr1*disij[1][temp_ik];
+                bt_sg[nb_ik].dAA[2]+=
+                    app1*dcAng[ang_jik][2][ngk]
+                    +agpdpr1*disij[2][temp_ik];
+ 
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k 
+
+                kp_index=0;
+                for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+                  temp_jkp=BOP_index[j]+ltmp;
+                  kp=jlist[ltmp];
+                  if(x[kp][0]==x[k][0]) {
+                    if(x[kp][1]==x[k][1]) {
+                      if(x[kp][2]==x[k][2]) {
+                        kp_index=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(kp_index) {
+ 
+//loop over neighbors of k
+ 
+                  for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+                    kp=klist[mtmp];
+                    if(x[kp][0]==x[j][0]) {
+                      if(x[kp][1]==x[j][1]) {
+                        if(x[kp][2]==x[j][2]) {
+                          break;
+                        }
+                      }
+                    }
+                  }
+                  if(ki<ltmp) {
+                    nijk=ki*(2*numneigh[j]-ki-1)/2+(ltmp-ki)-1;
+                    ngji=0;
+                    ngjk=1;
+                  }
+                  else {
+                    nijk=ltmp*(2*numneigh[j]-ltmp-1)/2+(ki-ltmp)-1;
+                    ngji=1;
+                    ngjk=0;
+                  }
+                  if(kNeii<mtmp) {
+                    nikj=kNeii*(2*numneigh[k]-kNeii-1)/2+(mtmp-kNeii)-1;
+                    ngki=0;
+                    ngkj=1;
+                  }
+                  else {
+                    nikj=mtmp*(2*numneigh[k]-mtmp-1)/2+(kNeii-mtmp)-1;
+                    ngki=1;
+                    ngkj=0;
+                  }
+                  ang_ijk=cos_index[j]+nijk;
+                  if(ang_ijk>=cos_total) {
+                    printf("2 error in cos %7d\n",ang_ijk);
+                    exit(1);
+                  }
+                  gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                  gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                  gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                  amean=cosAng[ang_ijk];
+                  gfactor2=gmean0+gmean1*amean
+                      +gmean2*amean*amean;
+                  gprime2=gmean1+2.0*gmean2*amean;
+                  gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+                  gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+                  gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+                  ang_ikj=cos_index[k]+nikj;
+                  if(ang_ikj>=cos_total) {
+                    printf("3 error in cos %7d\n",ang_ikj);
+                    exit(1);
+                  }
+                  amean=cosAng[ang_ikj];
+                  gfactor3=gmean0+gmean1*amean
+                      +gmean2*amean*amean;
+                  gprime3=gmean1+2.0*gmean2*amean;
+                  gfactor=gfactor1*gfactor2*gfactor3;
+                  rfactor=betaS[temp_ik]*betaS[temp_jkp];
+ 
+//EE1 is (b) Eq. 12
+ 
+                  EE1=EE1+gfactor*rfactor;
+ 
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+ 
+                  rcm1=gfactor*betaS[temp_jkp]*dBetaS[temp_ik]/rij[temp_ik];
+                  rcm2=gfactor*betaS[temp_ik]*dBetaS[temp_jkp]/rij[temp_jkp];
+                  gcm1=rfactor*gprime1*gfactor2*gfactor3;
+                  gcm2=rfactor*gfactor1*gprime2*gfactor3;
+                  gcm3=rfactor*gfactor1*gfactor2*gprime3;
+                  bt_sg[nb_ij].dEE1[0]+=
+                      gcm1*dcAng[ang_jik][0][ngj]
+                      -gcm2*dcAng[ang_ijk][0][ngji];
+                  bt_sg[nb_ij].dEE1[1]+=
+                      gcm1*dcAng[ang_jik][1][ngj]
+                      -gcm2*dcAng[ang_ijk][1][ngji];
+                  bt_sg[nb_ij].dEE1[2]+=
+                      gcm1*dcAng[ang_jik][2][ngj]
+                      -gcm2*dcAng[ang_ijk][2][ngji];
+                  bt_sg[nb_ik].dEE1[0]+=
+                      gcm1*dcAng[ang_jik][0][ngk]
+                      +rcm1*disij[0][temp_ik]
+                      -gcm3*dcAng[ang_ikj][0][ngki];
+                  bt_sg[nb_ik].dEE1[1]+=
+                      gcm1*dcAng[ang_jik][1][ngk]
+                      +rcm1*disij[1][temp_ik]
+                      -gcm3*dcAng[ang_ikj][1][ngki];
+                  bt_sg[nb_ik].dEE1[2]+=
+                      gcm1*dcAng[ang_jik][2][ngk]
+                      +rcm1*disij[2][temp_ik]
+                      -gcm3*dcAng[ang_ikj][2][ngki];
+                  bt_sg[nb_jk].dEE1[0]+=
+                      gcm2*dcAng[ang_ijk][0][ngjk]
+                      +rcm2*disij[0][temp_jkp]
+                      -gcm3*dcAng[ang_ikj][0][ngkj];
+                  bt_sg[nb_jk].dEE1[1]+=
+                      gcm2*dcAng[ang_ijk][1][ngjk]
+                      +rcm2*disij[1][temp_jkp]
+                      -gcm3*dcAng[ang_ikj][1][ngkj];
+                  bt_sg[nb_jk].dEE1[2]+=
+                      gcm2*dcAng[ang_ijk][2][ngjk]
+                      +rcm2*disij[2][temp_jkp]
+                      -gcm3*dcAng[ang_ikj][2][ngkj];
+                }
+ 
+// k and k' and j are all different neighbors of i
+ 
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=jtmp) {
+                    temp_ikp=BOP_index[i]+ltmp;
+                    if(neigh_flag[temp_ikp]) {
+                      kp=iilist[ltmp];
+                      kptype = map[type[kp]]+1;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("15 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(jtmp<ltmp) {
+                        njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+                        nglj=0;
+                        ngl=1;
+                      }
+                      else {
+                        njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+                        nglj=1;
+                        ngl=0;
+                      }
+                      if(ktmp<ltmp) {
+                        nkikp=ktmp*(2*numneigh[i]-ktmp-1)/2+(ltmp-ktmp)-1;
+                      }
+                      else {
+                        nkikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(ktmp-ltmp)-1;
+                      }
+                      ang_jikp=cos_index[i]+njikp;
+                      if(ang_jikp>=cos_total) {
+                        printf("4 error in cos %7d\n",ang_jikp);
+                        exit(1);
+                      }
+                      gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+                      amean=cosAng[ang_jikp];
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+                      ang_kikp=cos_index[i]+nkikp;
+                      if(ang_kikp>=cos_total) {
+                        printf("5 error in cos %7d\n",ang_kikp);
+                        exit(1);
+                      }
+                      amean=cosAng[ang_kikp];
+                      gfactor3=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS[temp_ik]*betaS[temp_ikp];
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+ 
+                      CC=CC+2.0*gfactor*rfactor;
+                    }
+                  }
+                }
+ 
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+ 
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  if(neigh_flag[temp_kkp]) {
+                    kp=klist[ltmp];;
+                    kptype = map[type[kp]]+1;
+                    same_ikp=0;
+                    same_jkp=0;
+                    if(x[i][0]==x[kp][0]) {
+                      if(x[i][1]==x[kp][1]) {
+                        if(x[i][2]==x[kp][2]) {
+                          same_ikp=1;
+                        }
+                      }
+                    }
+                    if(x[j][0]==x[kp][0]) {
+                      if(x[j][1]==x[kp][1]) {
+                        if(x[j][2]==x[kp][2]) {
+                          same_jkp=1;
+                        }
+                      }
+                    }
+                    if(!same_ikp&&!same_jkp) {
+                      if(kNeii<ltmp) {
+                        nikkp=kNeii*(2*numneigh[k]-kNeii-1)/2+(ltmp-kNeii)-1;
+                        ngli=0;
+                      }
+                      else {
+                        nikkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeii-ltmp)-1;
+                        ngli=1;
+                      }
+                      sig_flag=0;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("16 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              sig_flag=1;
+                              nkp=nsearch;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==0) {
+                        nSigBk[n]=nSigBk[n]+1;
+                        nkp=nSigBk[n]-1;
+                        if(nkp>=neigh_ct) {
+                          printf("17 too big nSigBk\n");
+                          exit(1);
+                        }
+                        itypeSigBk[n][nkp]=kp;
+                      }
+                      ang_ikkp=cos_index[k]+nikkp;
+                      if(ang_ikkp>=cos_total) {
+                        printf("6 error in cos %7d\n",ang_ikkp);
+                        exit(1);
+                      }
+                      gmean0=sigma_g0[itype-1][ktype-1][kptype-1];          
+                      gmean1=sigma_g1[itype-1][ktype-1][kptype-1];          
+                      gmean2=sigma_g2[itype-1][ktype-1][kptype-1];          
+                      amean=cosAng[ang_ikkp];
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS[temp_ik]*betaS[temp_kkp];
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//3rd CC is third term of Eq. 11 (c) for i atom 
+//where j , k =neighbor of i & k' =neighbor of k
+ 
+                      CC=CC+gfactor*rfactor;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        
+//j is a neighbor of i and k is a neighbor of j not equal to i
+ 
+          for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+            if(ktmp!=ji) {
+              if(ktmp<ji) {
+                njik=ktmp*(2*numneigh[j]-ktmp-1)/2+(ji-ktmp)-1;
+                ngi=1;
+                ngk=0;
+              }
+              else {
+                njik=ji*(2*numneigh[j]-ji-1)/2+(ktmp-ji)-1;
+                ngi=0;
+                ngk=1;
+              }
+              temp_jk=BOP_index[j]+ktmp;
+              if(neigh_flag[temp_jk]) {
+                k=jlist[ktmp];
+                ktype=map[type[k]]+1;
+                klist=firstneigh[k];
+ 
+                for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                  if(x[klist[kNeij]][0]==x[j][0]) {
+                    if(x[klist[kNeij]][1]==x[j][1]) {
+                      if(x[klist[kNeij]][2]==x[j][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+                sig_flag=0;
+                if(nSigBk[n]>neigh_ct) {
+                  printf("18 too big nSigBk\n");
+                  exit(1);
+                }
+                for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                  ncmp=itypeSigBk[n][nsearch];
+                  if(x[ncmp][0]==x[k][0]) {
+                    if(x[ncmp][1]==x[k][1]) {
+                      if(x[ncmp][2]==x[k][2]) {
+                        new1=nsearch;
+                        sig_flag=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(sig_flag==0) {
+                  nSigBk[n]=nSigBk[n]+1;
+                  new1=nSigBk[n]-1;
+                  if(new1>=neigh_ct) {
+                    printf("19 too big nSigBk\n");
+                    exit(1);
+                  }
+                  itypeSigBk[n][new1]=k;
+                }
+                ang_ijk=cos_index[j]+njik;
+                if(ang_ijk>=cos_total) {
+                  printf("7 error in cos %7d\n",ang_ijk);
+                  exit(1);
+                }
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                amean=cosAng[ang_ijk];
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gsqprime=2.0*gfactor1*gprime1;
+                rfactor1rt=betaS[temp_jk]*betaS[temp_jk];
+                rfactor1=rfactor1rt*rfactor1rt;
+ 
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+                BB=BB+gfactorsq*rfactor1rt;
+                DD=DD+gfactorsq*rfactor1;
+ 
+//agpdpr1 is derivative of BB  w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+ 
+                agpdpr1=2.0*gfactorsq*betaS[temp_jk]*dBetaS[temp_jk]/rij[temp_jk];
+                app1=rfactor1rt*gsqprime;
+                bt_sg[nb_ij].dBB[0]-=
+                    app1*dcAng[ang_ijk][0][ngi];
+                bt_sg[nb_ij].dBB[1]-=
+                    app1*dcAng[ang_ijk][1][ngi];
+                bt_sg[nb_ij].dBB[2]-=
+                    app1*dcAng[ang_ijk][2][ngi];
+                bt_sg[nb_jk].dBB[0]+=
+                    app1*dcAng[ang_ijk][0][ngk]
+                    +agpdpr1*disij[0][temp_jk];
+                bt_sg[nb_jk].dBB[1]+=
+                    app1*dcAng[ang_ijk][1][ngk]
+                    +agpdpr1*disij[1][temp_jk];
+                bt_sg[nb_jk].dBB[2]+=
+                    app1*dcAng[ang_ijk][2][ngk]
+                    +agpdpr1*disij[2][temp_jk];
+ 
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+ 
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=ji) {
+                    temp_jkp=BOP_index[j]+ltmp;
+                    if(neigh_flag[temp_jkp]) {
+                      kp=jlist[ltmp];
+                      kptype=map[type[kp]]+1;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("20 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              new2=nsearch;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(ji<ltmp) {
+                        nijkp=ji*(2*numneigh[j]-ji-1)/2+(ltmp-ji)-1;
+                        ngli=0;
+                        ngl=1;
+                      }
+                      else {
+                        nijkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ji-ltmp)-1;
+                        ngli=1;
+                        ngl=0;
+                      }
+                      if(ktmp<ltmp) {
+                        nkjkp=ktmp*(2*numneigh[j]-ktmp-1)/2+(ltmp-ktmp)-1;
+                        ngjk=0;
+                      }
+                      else {
+                        nkjkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ktmp-ltmp)-1;
+                        ngjk=1;
+                      }
+                      ang_ijkp=cos_index[j]+nijkp;
+                      if(ang_ijkp>=cos_total) {
+                        printf("8 error in cos %7d\n",ang_ijkp);
+                        exit(1);
+                      }
+                      ang_kjkp=cos_index[j]+nkjkp;
+                      if(ang_kjkp>=cos_total) {
+                        printf("9 error in cos %7d\n",ang_kjkp);
+                        exit(1);
+                      }
+                      gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+                      amean=cosAng[ang_ijkp];
+                      gfactor2=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+                      amean=cosAng[ang_kjkp];
+                      gfactor3=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS[temp_jk]*betaS[temp_jkp];
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+ 
+                      DD=DD+2.0*gfactor*rfactor;
+                    }
+                  }
+                }
+ 
+//j is a neighbor of i, k is a neighbor of j not equal to i and k' 
+//is a neighbor of k not equal to j or i
+ 
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  if(neigh_flag[temp_kkp]) {
+                    kp=klist[ltmp];
+                    kptype=map[type[kp]]+1;
+                    same_ikp=0;
+                    same_jkp=0;
+                    if(x[i][0]==x[kp][0]) {
+                      if(x[i][1]==x[kp][1]) {
+                        if(x[i][2]==x[kp][2]) {
+                          same_ikp=1;
+                        }
+                      }
+                    }
+                    if(x[j][0]==x[kp][0]) {
+                      if(x[j][1]==x[kp][1]) {
+                        if(x[j][2]==x[kp][2]) {
+                          same_jkp=1;
+                        }
+                      }
+                    }
+                    if(!same_ikp&&!same_jkp) {
+                      for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                        if(x[klist[kNeij]][0]==x[j][0]) {
+                          if(x[klist[kNeij]][1]==x[j][1]) {
+                            if(x[klist[kNeij]][2]==x[j][2]) {
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(kNeij<ltmp) {
+                        njkkp=kNeij*(2*numneigh[k]-kNeij-1)/2+(ltmp-kNeij)-1;
+                        nglj=0;
+                      }
+                      else {
+                        njkkp=ltmp*(2*numneigh[k]-ltmp-1)/2+(kNeij-ltmp)-1;
+                        nglj=1;
+                      }
+                      sig_flag=0;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("21 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              new2=nsearch;
+                              sig_flag=1;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==0) {
+                        nSigBk[n]=nSigBk[n]+1;
+                        new2=nSigBk[n]-1;
+                        if(new2>=neigh_ct) {
+                          printf("22 too big nSigBk %7d %7d\n",new2,neigh_ct);
+                          exit(1);
+                        }
+                        itypeSigBk[n][new2]=kp;
+                      }
+                      ang_jkkp=cos_index[k]+njkkp;
+                      if(ang_jkkp>=cos_total) {
+                        printf("10 error in cos %7d\n",ang_jkkp);
+                        exit(1);
+                      }
+                      gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+                      amean=cosAng[ang_jkkp];
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS[temp_jk]*betaS[temp_kkp];
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+ 
+                      DD=DD+gfactor*rfactor;
+                    }
+                  }
+                }
+              }
+            }
+          }
+ 
+          sig_flag=0;
+          if(sig_flag==0) {
+ 
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+ 
+            AAC=AA+BB;
+            BBC=AA*BB;
+            CCC=AA*AA+BB*BB;
+            DDC=CC+DD;
+ 
+//EEC is a modified form of (a) Eq. 33
+ 
+            EEC=(DDC-CCC)/(AAC+2.0*small1);
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                bt_i=bt_sg[m].i;
+                bt_j=bt_sg[m].j;
+                bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+                    +bt_sg[m].dBB[0];
+                bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+                    +bt_sg[m].dBB[1];
+                bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+                    +bt_sg[m].dBB[2];
+              } 
+            }
+            UT=EEC*FF+BBC+small3[iij];
+            UT=1.0/sqrt(UT);
+
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+ 
+            bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])
+                +sigma_c[iij]*AAC+small4;
+            UTcom=-0.5*UT*UT*UT;
+            psign=1.0;
+            bndtmp0=1.0/sqrt(bndtmp);
+            sigB1[n]=psign*betaS[temp_ij]*bndtmp0;
+            bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+            bndtmp1=psign*bndtmp0+psign*betaS[temp_ij]
+                *bndtmp*2.0*betaS[temp_ij];
+            bndtmp1=bndtmp1*dBetaS[temp_ij]/rij[temp_ij];
+            bndtmp2=psign*betaS[temp_ij]*bndtmp*sigma_c[iij];
+            setting=0;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                if(temp_kk==temp_ij&&setting==0) {
+                  bt_sg[m].dSigB1[0]=bndtmp1*disij[0][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[0]);
+                  bt_sg[m].dSigB1[1]=bndtmp1*disij[1][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[1]);
+                  bt_sg[m].dSigB1[2]=bndtmp1*disij[2][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[2]);
+                  setting=1;
+                }
+                else if(temp_kk==temp_ji&&setting==0) {
+                  bt_sg[m].dSigB1[0]=-bndtmp1*disij[0][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[0]);
+                  bt_sg[m].dSigB1[1]=-bndtmp1*disij[1][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[1]);
+                  bt_sg[m].dSigB1[2]=-bndtmp1*disij[2][temp_ij]
+                      +(bndtmp2*bt_sg[m].dAAC[2]);
+                  setting=1;
+                }
+                else {
+                  bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]);
+                  bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]);
+                  bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]);
+                }
+              }
+            }
+ 
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+
+            if(nb_t==0) {
+              if(j>i) {
+                bt_sg[0].dSigB1[0]=bndtmp1*disij[0][temp_ij];
+                bt_sg[0].dSigB1[1]=bndtmp1*disij[1][temp_ij];
+                bt_sg[0].dSigB1[2]=bndtmp1*disij[2][temp_ij];
+              }
+              else {
+                bt_sg[0].dSigB1[0]=-bndtmp1*disij[0][temp_ij];
+                bt_sg[0].dSigB1[1]=-bndtmp1*disij[1][temp_ij];
+                bt_sg[0].dSigB1[2]=-bndtmp1*disij[2][temp_ij];
+              }
+              for(pp=0;pp<3;pp++) {
+                bt_sg[0].dAA[pp]=0.0;
+                bt_sg[0].dBB[pp]=0.0;
+                bt_sg[0].dEE1[pp]=0.0;
+                bt_sg[0].dFF[pp]=0.0;
+                bt_sg[0].dAAC[pp]=0.0;
+                bt_sg[0].dSigB[pp]=0.0;
+              }
+              bt_sg[0].i=i;
+              bt_sg[0].j=j;
+              bt_sg[0].temp=temp_ij;
+              nb_t++;
+              if(nb_t>nb_sg) {
+                new_n_tot=nb_sg+maxneigh;
+                grow_sigma(nb_sg,new_n_tot);
+                nb_sg=new_n_tot;
+              }
+            }
+            ps=sigB1[n]*rdBO+1.0;
+            ks=(int)ps;
+            if(nBOt-1<ks)
+              ks=nBOt-1;
+            ps=ps-ks;
+            if(ps>1.0)
+              ps=1.0;
+            dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+                +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+            dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+            part0=(FF+0.5*AAC+small5);
+            part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+            part2=1.0-part1*EE1/part0;
+            part3=dsigB1*part1/part0;
+            part4=part3/part0*EE1;
+ 
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+ 
+            sigB[n]=dsigB1*part2;
+            pp1=2.0*betaS[temp_ij];
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                bt_ij=bt_sg[m].temp;
+                bt_i=bt_sg[m].i;
+                bt_j=bt_sg[m].j;
+                for(pp=0;pp<3;pp++) {
+                  bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+                      -part3*bt_sg[m].dEE1[pp]
+                      +part4*(bt_sg[m].dFF[pp]
+                      +0.5*bt_sg[m].dAAC[pp]);
+                }
+                for(pp=0;pp<3;pp++) {
+                  ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+                  f[bt_i][pp]-=ftmp[pp];
+                  f[bt_j][pp]+=ftmp[pp];
+                }
+                if(evflag) {
+                  ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                      ,ftmp[2],disij[0][bt_ij],disij[1][bt_ij],disij[2][bt_ij]);
+                }
+              }
+            }
+          }
+          n++;
+        }
+      }
+    }
+  }
+  destroy_sigma();
+}
+ 
+/*  The formulation differs slightly to avoid negative square roots
+    in the calculation of Theta_pi,ij of (a) Eq. 36 and (b) Eq. 18 */
+
+void PairBOP::sigmaBo_otf()
+{
+  int nb_t,new_n_tot;
+  int n,i,j,k,kp,m,pp,kpj,kpk,kkp;
+  int itmp,jtmp,ktmp,ltmp,mtmp;
+  int i_tag,j_tag;
+  int kp1,kp2,kp1type;
+  int iij,iik,ijk,ikkp,ji,iikp,ijkp;
+  int nkp;
+  int nk0;
+  int jNeik,kNeii,kNeij,kNeikp;
+  int kpNeij,kpNeik;
+  int new1,new2,nlocal;
+  int inum,*ilist,*iilist,*jlist,*klist,*kplist;
+  int **firstneigh,*numneigh; 
+  int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+  int temp_ji,temp_kpj,temp_kkp;
+  int temp_ikp,temp_kpk;
+  int nb_ij,nb_ik,nb_ikp;
+  int nb_jk,nb_jkp,nb_kkp;
+  int kp_nsearch,nsearch;
+  int sig_flag,setting,ncmp,ks;
+  int itype,jtype,ktype,kptype;
+  int bt_i,bt_j;
+  int same_ikp,same_jkp,same_kpk;
+  int same_jkpj,same_kkpk;
+  double AA,BB,CC,DD,EE,EE1,FF;
+  double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+  double AACFF,UT,bndtmp,UTcom;
+  double amean,gmean0,gmean1,gmean2,ps;
+  double gfactor1,gprime1,gsqprime,factorsq;
+  double gfactorsq,gfactor2,gprime2;
+  double gfactorsq2,gsqprime2;
+  double gfactor3,gprime3,gfactor,rfactor;
+  double drfactor,gfactor4,gprime4,agpdpr3;
+  double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+  double rcm1,rcm2,gcm1,gcm2,gcm3;
+  double agpdpr1,agpdpr2,app1,app2,app3,app4;
+  double dsigB1,dsigB2;
+  double part0,part1,part2,part3,part4;
+  double psign,bndtmp0,pp1;
+  double bndtmp1,bndtmp2,bndtmp3,bndtmp4,bndtmp5;
+  double dis_ij[3],rsq_ij,r_ij;
+  double betaS_ij,dBetaS_ij;
+  double betaP_ij,dBetaP_ij;
+  double dis_ik[3],rsq_ik,r_ik;
+  double betaS_ik,dBetaS_ik;
+  double betaP_ik,dBetaP_ik;
+  double dis_ikp[3],rsq_ikp,r_ikp;
+  double betaS_ikp,dBetaS_ikp;
+  double betaP_ikp,dBetaP_ikp;
+  double dis_jk[3],rsq_jk,r_jk;
+  double betaS_jk,dBetaS_jk;
+  double betaP_jk,dBetaP_jk;
+  double dis_jkp[3],rsq_jkp,r_jkp;
+  double betaS_jkp,dBetaS_jkp;
+  double betaP_jkp,dBetaP_jkp;
+  double dis_kkp[3],rsq_kkp,r_kkp;
+  double betaS_kkp,dBetaS_kkp;
+  double betaP_kkp,dBetaP_kkp;
+  double cosAng_jik,dcA_jik[3][2];
+  double cosAng_jikp,dcA_jikp[3][2];
+  double cosAng_kikp,dcA_kikp[3][2];
+  double cosAng_ijk,dcA_ijk[3][2];
+  double cosAng_ijkp,dcA_ijkp[3][2];
+  double cosAng_kjkp,dcA_kjkp[3][2];
+  double cosAng_ikj,dcA_ikj[3][2];
+  double cosAng_ikkp,dcA_ikkp[3][2];
+  double cosAng_jkkp,dcA_jkkp[3][2];
+  double cosAng_jkpk,dcA_jkpk[3][2];
+
+  double ftmp[3],xtmp[3];
+  double **x = atom->x;
+  double **f = atom->f;
+  int *tag = atom->tag;
+  int newton_pair = force->newton_pair;
+  int *type = atom->type;
+
+  nlocal = atom->nlocal;
+  int nall = nlocal + atom->nghost;
+  inum = list->inum; 
+  ilist = list->ilist;
+  numneigh = list->numneigh;
+  firstneigh = list->firstneigh;
+
+  n=0;
+  if(nb_sg==0) {
+    nb_sg=(maxneigh)*(maxneigh/2);
+  }
+  if(allocate_sigma) {
+    destroy_sigma();
+  }
+  
+  create_sigma(nb_sg);
+
+  for(itmp=0;itmp<inum;itmp++) {
+    i = ilist[itmp];
+    i_tag=tag[i];  
+    itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+
+    if(numneigh[i]>maxneigh) {
+      printf("split neighbor error!\n");
+      exit(1);
+    } 
+    for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+      for(m=0;m<nb_sg;m++) {
+        for(pp=0;pp<3;pp++) {
+          bt_sg[m].dAA[pp]=0.0;
+          bt_sg[m].dBB[pp]=0.0;
+          bt_sg[m].dCC[pp]=0.0;
+          bt_sg[m].dDD[pp]=0.0;
+          bt_sg[m].dEE[pp]=0.0;
+          bt_sg[m].dEE1[pp]=0.0;
+          bt_sg[m].dFF[pp]=0.0;
+          bt_sg[m].dAAC[pp]=0.0;
+          bt_sg[m].dBBC[pp]=0.0;
+          bt_sg[m].dCCC[pp]=0.0;
+          bt_sg[m].dDDC[pp]=0.0;
+          bt_sg[m].dEEC[pp]=0.0;
+          bt_sg[m].dFFC[pp]=0.0;
+          bt_sg[m].dGGC[pp]=0.0;
+          bt_sg[m].dUT[pp]=0.0;
+          bt_sg[m].dSigB1[pp]=0.0;
+          bt_sg[m].dSigB[pp]=0.0;
+        }
+        bt_sg[m].i=-1;
+        bt_sg[m].j=-1;
+        bt_sg[m].temp=-1;
+      }
+      nb_t=0;
+      iilist=firstneigh[i];
+      temp_ij=BOP_index[i]+jtmp;
+      j=iilist[jtmp];
+      jlist=firstneigh[j];
+      j_tag=tag[j];
+      jtype = map[type[j]]+1;
+      nb_ij=nb_t;
+      nb_t++;
+      if(nb_t>nb_sg) {
+        new_n_tot=nb_sg+maxneigh;
+        grow_sigma(nb_sg,new_n_tot);
+        nb_sg=new_n_tot;
+      }
+      bt_sg[nb_ij].temp=temp_ij;
+      bt_sg[nb_ij].i=i;
+      bt_sg[nb_ij].j=j;
+      if(j_tag>=i_tag) {
+        if(n>=neigh_total) {
+          printf("BOP 16:n is too large \n");
+          exit(1);
+        }
+        if(itype==jtype)
+          iij=itype-1;
+        else if(itype<jtype)
+          iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+        else
+          iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+        for(ji=0;ji<numneigh[j];ji++) {
+          temp_ji=BOP_index[j]+ji;
+          if(x[jlist[ji]][0]==x[i][0]) {
+            if(x[jlist[ji]][1]==x[i][1]) {
+              if(x[jlist[ji]][2]==x[i][2]) {
+                break;
+              }
+            }
+          }
+        }
+        dis_ij[0]=x[j][0]-x[i][0]; 
+        dis_ij[1]=x[j][1]-x[i][1]; 
+        dis_ij[2]=x[j][2]-x[i][2]; 
+        rsq_ij=dis_ij[0]*dis_ij[0]
+            +dis_ij[1]*dis_ij[1]
+            +dis_ij[2]*dis_ij[2];
+        r_ij=sqrt(rsq_ij); 
+
+        if(r_ij<rcut[iij]) {
+          ps=r_ij*rdr[iij]+1.0;
+          ks=(int)ps;
+          if(nr-1<ks)
+            ks=nr-1;
+          ps=ps-ks;
+          if(ps>1.0)
+            ps=1.0;
+          betaS_ij=((pBetaS3[iij][ks-1]*ps+pBetaS2[iij][ks-1])*ps
+              +pBetaS1[iij][ks-1])*ps+pBetaS[iij][ks-1];
+          dBetaS_ij=(pBetaS6[iij][ks-1]*ps+pBetaS5[iij][ks-1])*ps
+              +pBetaS4[iij][ks-1];
+          betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+              +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+          dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+              +pBetaP4[iij][ks-1];
+          nSigBk[n]=0;
+
+//AA-EE1 are the components making up Eq. 30 (a)
+
+          AA=0.0;
+          BB=0.0;
+          CC=0.0;
+          DD=0.0;
+          EE=0.0;
+          EE1=0.0;
+
+//FF is the Beta_sigma^2 term
+       
+          FF=betaS_ij*betaS_ij;
+
+//agpdpr1 is derivative of FF w.r.t. r_ij
+
+          agpdpr1=2.0*betaS_ij*dBetaS_ij/r_ij;
+
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+
+          bt_sg[nb_ij].dFF[0]=agpdpr1*dis_ij[0];
+          bt_sg[nb_ij].dFF[1]=agpdpr1*dis_ij[1];
+          bt_sg[nb_ij].dFF[2]=agpdpr1*dis_ij[2];
+
+//k is loop over all neighbors of i again with j neighbor of i 
+
+          for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+            temp_ik=BOP_index[i]+ktmp;
+            if(ktmp!=jtmp) {
+              k=iilist[ktmp];
+              klist=firstneigh[k];
+              ktype = map[type[k]]+1;
+              if(itype==ktype)
+                iik=itype-1;
+              else if(itype<ktype)
+                iik=itype*bop_types-itype*(itype+1)/2+ktype-1;
+              else
+                iik=ktype*bop_types-ktype*(ktype+1)/2+itype-1;
+  
+//find neighbor of k that is equal to i
+
+              for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+                if(x[klist[kNeii]][0]==x[i][0]) {
+                  if(x[klist[kNeii]][1]==x[i][1]) {
+                    if(x[klist[kNeii]][2]==x[i][2]) {
+                      break;
+                    }
+                  }
+                }
+              }
+              dis_ik[0]=x[k][0]-x[i][0]; 
+              dis_ik[1]=x[k][1]-x[i][1]; 
+              dis_ik[2]=x[k][2]-x[i][2]; 
+              rsq_ik=dis_ik[0]*dis_ik[0]
+                  +dis_ik[1]*dis_ik[1]
+                  +dis_ik[2]*dis_ik[2];
+              r_ik=sqrt(rsq_ik); 
+              if(r_ik<=rcut[iik]) {
+                ps=r_ik*rdr[iik]+1.0;
+                ks=(int)ps;
+                if(nr-1<ks)
+                  ks=nr-1;
+                ps=ps-ks;
+                if(ps>1.0)
+                  ps=1.0;
+                betaS_ik=((pBetaS3[iik][ks-1]*ps+pBetaS2[iik][ks-1])*ps
+                    +pBetaS1[iik][ks-1])*ps+pBetaS[iik][ks-1];
+                dBetaS_ik=(pBetaS6[iik][ks-1]*ps+pBetaS5[iik][ks-1])*ps
+                    +pBetaS4[iik][ks-1];
+                betaP_ik=((pBetaP3[iik][ks-1]*ps+pBetaP2[iik][ks-1])*ps
+                    +pBetaP1[iik][ks-1])*ps+pBetaP[iik][ks-1];
+                dBetaP_ik=(pBetaP6[iik][ks-1]*ps+pBetaP5[iik][ks-1])*ps
+                    +pBetaP4[iik][ks-1];
+
+//find neighbor of i that is equal to k
+
+                for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+                  temp_jk=BOP_index[j]+jNeik;
+                  if(x[jlist[jNeik]][0]==x[k][0]) {
+                    if(x[jlist[jNeik]][1]==x[k][1]) {
+                      if(x[jlist[jNeik]][2]==x[k][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+
+//find neighbor of k that is equal to j
+
+                for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                  if(x[klist[kNeij]][0]==x[j][0]) {
+                    if(x[klist[kNeij]][1]==x[j][1]) {
+                      if(x[klist[kNeij]][2]==x[j][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+                dis_jk[0]=x[k][0]-x[j][0]; 
+                dis_jk[1]=x[k][1]-x[j][1]; 
+                dis_jk[2]=x[k][2]-x[j][2]; 
+                rsq_jk=dis_jk[0]*dis_jk[0]
+                    +dis_jk[1]*dis_jk[1]
+                    +dis_jk[2]*dis_jk[2];
+                r_jk=sqrt(rsq_jk); 
+
+                sig_flag=0;
+                if(nSigBk[n]>neigh_ct) {
+                  printf("23 too big nSigBk\n");
+                  exit(1);
+                }
+                for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                  ncmp=itypeSigBk[n][nsearch];
+                  if(x[ncmp][0]==x[k][0]) {
+                    if(x[ncmp][1]==x[k][1]) {
+                      if(x[ncmp][2]==x[k][2]) {
+                        nk0=nsearch;
+                        sig_flag=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(sig_flag==0) {
+                  nSigBk[n]=nSigBk[n]+1;
+                  nk0=nSigBk[n]-1;
+                  if(nk0>=neigh_ct) {
+                    printf("24 too big nSigBk\n");
+                    exit(1);
+                  }
+                  itypeSigBk[n][nk0]=k;
+                }
+                nb_ik=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_ik].temp=temp_ik;
+                bt_sg[nb_ik].i=i;
+                bt_sg[nb_ik].j=k;
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                cosAng_jik=(dis_ij[0]*dis_ik[0]+dis_ij[1]*dis_ik[1]
+                    +dis_ij[2]*dis_ik[2])/(r_ij*r_ik); 
+                dcA_jik[0][0]=(dis_ik[0]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[0]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[1][0]=(dis_ik[1]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[1]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[2][0]=(dis_ik[2]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[2]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[0][1]=(dis_ij[0]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[0]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[1][1]=(dis_ij[1]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[1]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[2][1]=(dis_ij[2]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[2]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+                gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+                gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+                amean=cosAng_jik;
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gsqprime=2.0*gfactor1*gprime1;
+
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+
+                AA=AA+gfactorsq*betaS_ik*betaS_ik;
+                CC=CC+gfactorsq*betaS_ik*betaS_ik*betaS_ik*betaS_ik;
+
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+
+                agpdpr1=2.0*gfactorsq*betaS_ik*dBetaS_ik/r_ik;
+                app1=betaS_ik*betaS_ik*gsqprime;
+                bt_sg[nb_ij].dAA[0]+=
+                    app1*dcA_jik[0][0];
+                bt_sg[nb_ij].dAA[1]+=
+                    app1*dcA_jik[1][0];
+                bt_sg[nb_ij].dAA[2]+=
+                    app1*dcA_jik[2][0];
+                bt_sg[nb_ij].dCC[0]+=
+                    app2*dcA_jik[0][0];
+                bt_sg[nb_ij].dCC[1]+=
+                    app2*dcA_jik[1][0];
+                bt_sg[nb_ij].dCC[2]+=
+                    app2*dcA_jik[2][0];
+                bt_sg[nb_ik].dAA[0]+=
+                    app1*dcA_jik[0][1]
+                    +agpdpr1*dis_ik[0];
+                bt_sg[nb_ik].dAA[1]+=
+                    app1*dcA_jik[1][1]
+                    +agpdpr1*dis_ik[1];
+                bt_sg[nb_ik].dAA[2]+=
+                    app1*dcA_jik[2][1]
+                    +agpdpr1*dis_ik[2];
+                bt_sg[nb_ik].dCC[0]+=
+                    app2*dcA_jik[0][1]
+                    +agpdpr2*dis_ik[0];
+                bt_sg[nb_ik].dCC[1]+=
+                    app2*dcA_jik[1][1]
+                    +agpdpr2*dis_ik[1];
+                bt_sg[nb_ik].dCC[2]+=
+                    app2*dcA_jik[2][1]
+                    +agpdpr2*dis_ik[2];
+
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k 
+                
+                same_kpk=0; 
+                for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+                  temp_jkp=BOP_index[j]+ltmp;
+                  kp1=jlist[ltmp];
+                  kp1type=map[type[kp1]]+1;
+                  if(x[kp1][0]==x[k][0]) {
+                    if(x[kp1][1]==x[k][1]) {
+                      if(x[kp1][2]==x[k][2]) {
+                        same_kpk=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(same_kpk){
+
+//loop over neighbors of k
+
+                  for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+                    temp_kpj=BOP_index[k]+mtmp;
+                    kp2=klist[mtmp];
+                    if(x[kp2][0]==x[k][0]) {
+                      if(x[kp2][1]==x[k][1]) {
+                        if(x[kp2][2]==x[k][2]) {
+                          break;
+                        }
+                      }
+                    }
+                  }
+                  if(jtype==ktype)
+                    ijk=jtype-1;
+                  else if(jtype < ktype)
+                    ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+                  else
+                    ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+                  if(jtype==kp1type)
+                    ijkp=jtype-1;
+                  else if(jtype<kp1type)
+                    ijkp=jtype*bop_types-jtype*(jtype+1)/2+kp1type-1;
+                  else
+                    ijkp=kp1type*bop_types-kp1type*(kp1type+1)/2+jtype-1;
+
+                  dis_jkp[0]=x[kp1][0]-x[j][0]; 
+                  dis_jkp[1]=x[kp1][1]-x[j][1]; 
+                  dis_jkp[2]=x[kp1][2]-x[j][2]; 
+                  rsq_jkp=dis_jkp[0]*dis_jkp[0]
+                      +dis_jkp[1]*dis_jkp[1]
+                      +dis_jkp[2]*dis_jkp[2];
+                  r_jkp=sqrt(rsq_jkp); 
+                  if(r_jkp<=rcut[ijkp]) {
+                    ps=r_jkp*rdr[ijkp]+1.0;
+                    ks=(int)ps;
+                    if(nr-1<ks)
+                      ks=nr-1;
+                    ps=ps-ks;
+                    if(ps>1.0)
+                      ps=1.0;
+                    betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+                        +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+                    dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+                        +pBetaS4[ijkp][ks-1];
+                    betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+                        +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+                    dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+                        +pBetaP4[ijkp][ks-1];
+                    cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+                        -dis_ij[2]*dis_jk[2])/(r_ij*r_jk); 
+                    dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+                        *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+                        *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+                        *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+                        *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+                        *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+                        *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                    gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                    gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                    gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                    amean=cosAng_ijk;
+                    gfactor2=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                    gprime2=gmean1+2.0*gmean2*amean;
+                    gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+                    gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+                    gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+                    cosAng_ikj=(dis_ik[0]*dis_jk[0]+dis_ik[1]*dis_jk[1]
+                        +dis_ik[2]*dis_jk[2])/(r_ik*r_jk); 
+                    dcA_ikj[0][0]=(-dis_jk[0]*r_ik*r_jk-cosAng_ikj
+                        *-dis_ik[0]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[1][0]=(-dis_jk[1]*r_ik*r_jk-cosAng_ikj
+                        *-dis_ik[1]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[2][0]=(-dis_jk[2]*r_ik*r_jk-cosAng_ikj
+                        *-dis_ik[2]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[0][1]=(-dis_ik[0]*r_ik*r_jk-cosAng_ikj
+                        *-dis_jk[0]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[1][1]=(-dis_ik[1]*r_ik*r_jk-cosAng_ikj
+                        *-dis_jk[1]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[2][1]=(-dis_ik[2]*r_ik*r_jk-cosAng_ikj
+                        *-dis_jk[2]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+                    amean=cosAng_ikj;
+                    gfactor3=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                    gprime3=gmean1+2.0*gmean2*amean;
+                    gfactor=gfactor1*gfactor2*gfactor3;
+                    rfactor=betaS_ik*betaS_jkp;
+
+//EE1 is (b) Eq. 12
+
+                    EE1=EE1+gfactor*rfactor;
+
+//rcm1 is derivative of EE1 w.r.t Beta(r_ik)
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+
+                    rcm1=gfactor*betaS_jkp*dBetaS_ik/r_ik;
+                    rcm2=gfactor*betaS_ik*dBetaS_jkp/r_jkp;
+                    gcm1=rfactor*gprime1*gfactor2*gfactor3;
+                    gcm2=rfactor*gfactor1*gprime2*gfactor3;
+                    gcm3=rfactor*gfactor1*gfactor2*gprime3;
+                    bt_sg[nb_ij].dEE1[0]+=
+                        gcm1*dcA_jik[0][0]
+                        -gcm2*dcA_ijk[0][0];
+                    bt_sg[nb_ij].dEE1[1]+=
+                        gcm1*dcA_jik[1][0]
+                        -gcm2*dcA_ijk[1][0];
+                    bt_sg[nb_ij].dEE1[2]+=
+                        gcm1*dcA_jik[2][0]
+                        -gcm2*dcA_ijk[2][0];
+                    bt_sg[nb_ik].dEE1[0]+=
+                        gcm1*dcA_jik[0][1]
+                        +rcm1*dis_ik[0]
+                        -gcm3*dcA_ikj[0][0];
+                    bt_sg[nb_ik].dEE1[1]+=
+                        gcm1*dcA_jik[1][1]
+                        +rcm1*dis_ik[1]
+                        -gcm3*dcA_ikj[1][0];
+                    bt_sg[nb_ik].dEE1[2]+=
+                        gcm1*dcA_jik[2][1]
+                        +rcm1*dis_ik[2]
+                        -gcm3*dcA_ikj[2][0];
+                    bt_sg[nb_jk].dEE1[0]+=
+                        gcm2*dcA_ijk[0][1]
+                        +rcm2*dis_jkp[0]
+                        -gcm3*dcA_ikj[0][1];
+                    bt_sg[nb_jk].dEE1[1]+=
+                        gcm2*dcA_ijk[1][1]
+                        +rcm2*dis_jkp[1]
+                        -gcm3*dcA_ikj[1][1];
+                    bt_sg[nb_jk].dEE1[2]+=
+                        gcm2*dcA_ijk[2][1]
+                        +rcm2*dis_jkp[2]
+                        -gcm3*dcA_ikj[2][1];
+                  }
+                }
+
+// k and k' and j are all different neighbors of i
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=jtmp) {
+                    temp_ikp=BOP_index[i]+ltmp;
+                    kp=iilist[ltmp];;
+                    kptype = map[type[kp]]+1;
+                    if(itype==kptype)
+                      iikp=itype-1;
+                    else if(itype<kptype)
+                      iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+                    else
+                      iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+                    if(nSigBk[n]>neigh_ct) {
+                      printf("25 too big nSigBk\n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                      ncmp=itypeSigBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    dis_ikp[0]=x[kp][0]-x[i][0]; 
+                    dis_ikp[1]=x[kp][1]-x[i][1]; 
+                    dis_ikp[2]=x[kp][2]-x[i][2]; 
+                    rsq_ikp=dis_ikp[0]*dis_ikp[0]
+                        +dis_ikp[1]*dis_ikp[1]
+                        +dis_ikp[2]*dis_ikp[2];
+                    r_ikp=sqrt(rsq_ikp); 
+                    if(r_ikp<=rcut[iikp]) {
+                      ps=r_ikp*rdr[iikp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+                          +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+                      dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+                          +pBetaS4[iikp][ks-1];
+                      betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+                          +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+                      dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+                          +pBetaP4[iikp][ks-1];
+                      nb_ikp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_ikp].temp=temp_ikp;
+                      bt_sg[nb_ikp].i=i;
+                      bt_sg[nb_ikp].j=kp;
+                      gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+                      cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+                          +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp); 
+                      dcA_jikp[0][0]=(dis_ikp[0]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[0]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[1][0]=(dis_ikp[1]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[1]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[2][0]=(dis_ikp[2]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[2]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[0][1]=(dis_ij[0]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[0]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[1][1]=(dis_ij[1]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[1]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[2][1]=(dis_ij[2]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[2]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      cosAng_kikp=(dis_ik[0]*dis_ikp[0]+dis_ik[1]*dis_ikp[1]
+                          +dis_ik[2]*dis_ikp[2])/(r_ik*r_ikp); 
+                      dcA_kikp[0][0]=(dis_ikp[0]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ik[0]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[1][0]=(dis_ikp[1]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ik[1]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[2][0]=(dis_ikp[2]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ik[2]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[0][1]=(dis_ik[0]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ikp[0]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[1][1]=(dis_ik[1]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ikp[1]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[2][1]=(dis_ik[2]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ikp[2]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+                      amean=cosAng_jikp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+                      amean=cosAng_kikp;
+                      gfactor3=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS_ik*betaS_ikp;
+                      rfactor=rfactorrt*rfactorrt;
+
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+
+                      CC=CC+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of CC 2nd term w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of CC 2nd term w.r.t. Beta(r_ik')
+//app1 is derivative of CC 2nd term w.r.t. cos(theta_jik)
+//app2 is derivative of CC 2nd term w.r.t. cos(theta_jik')
+//app3 is derivative of CC 2nd term w.r.t. cos(theta_kik')
+ 
+                      agpdpr1=4.0*gfactor*rfactorrt*betaS_ikp
+                          *dBetaS_ik/r_ik;
+                      agpdpr2=4.0*gfactor*rfactorrt*betaS_ik
+                          *dBetaS_ikp/r_ikp;
+                      app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+                      app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+                      app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+                      bt_sg[nb_ij].dCC[0]+=
+                          app1*dcA_jik[0][0]
+                          +app2*dcA_jikp[0][0];
+                      bt_sg[nb_ij].dCC[1]+=
+                          app1*dcA_jik[1][0]
+                          +app2*dcA_jikp[1][0];
+                      bt_sg[nb_ij].dCC[2]+=
+                          app1*dcA_jik[2][0]
+                          +app2*dcA_jikp[2][0];
+                      bt_sg[nb_ik].dCC[0]+=
+                          app1*dcA_jik[0][1]
+                          +app3*dcA_kikp[0][0]
+                          +agpdpr1*dis_ik[0];
+                      bt_sg[nb_ik].dCC[1]+=
+                          app1*dcA_jik[1][1]
+                          +app3*dcA_kikp[1][0]
+                          +agpdpr1*dis_ik[1];
+                      bt_sg[nb_ik].dCC[2]+=
+                          app1*dcA_jik[2][1]
+                          +app3*dcA_kikp[2][0]
+                          +agpdpr1*dis_ik[2];
+                      bt_sg[nb_ikp].dCC[0]=
+                          app2*dcA_jikp[0][1]
+                          +app3*dcA_kikp[0][1]
+                          +agpdpr2*dis_ikp[0];
+                      bt_sg[nb_ikp].dCC[1]=
+                          app2*dcA_jikp[1][1]
+                          +app3*dcA_kikp[1][1]
+                          +agpdpr2*dis_ikp[1];
+                      bt_sg[nb_ikp].dCC[2]=
+                          app2*dcA_jikp[2][1]
+                          +app3*dcA_kikp[2][1]
+                          +agpdpr2*dis_ikp[2];
+                    }
+                  }
+                }
+
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  kp=klist[ltmp];;
+                  kptype = map[type[kp]]+1;
+                  same_ikp=0;
+                  same_jkp=0;
+                  if(x[i][0]==x[kp][0]) {
+                    if(x[i][1]==x[kp][1]) {
+                      if(x[i][2]==x[kp][2]) {
+                        same_ikp=1;
+                      }
+                    }
+                  }
+                  if(x[j][0]==x[kp][0]) {
+                    if(x[j][1]==x[kp][1]) {
+                      if(x[j][2]==x[kp][2]) {
+                        same_jkp=1;
+                      }
+                    }
+                  }
+                  if(!same_ikp&&!same_jkp) {
+                    if(ktype==kptype)
+                      ikkp=ktype-1;
+                    else if(ktype<kptype)
+                      ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+                    else
+                      ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+                    dis_kkp[0]=x[kp][0]-x[k][0]; 
+                    dis_kkp[1]=x[kp][1]-x[k][1]; 
+                    dis_kkp[2]=x[kp][2]-x[k][2]; 
+                    rsq_kkp=dis_kkp[0]*dis_kkp[0]
+                        +dis_kkp[1]*dis_kkp[1]
+                        +dis_kkp[2]*dis_kkp[2];
+                    r_kkp=sqrt(rsq_kkp); 
+                    if(r_kkp<=rcut[ikkp]) {
+                      ps=r_kkp*rdr[ikkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+                          +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+                      dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+                          +pBetaS4[ikkp][ks-1];
+                      betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+                          +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+                      dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+                          +pBetaP4[ikkp][ks-1];
+                      sig_flag=0;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("26 too big nSigBk\n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              sig_flag=1;
+                              nkp=nsearch;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==0) {
+                        nSigBk[n]=nSigBk[n]+1;
+                        nkp=nSigBk[n]-1;
+                        if(nkp>=neigh_ct) {
+                          printf("27 too big nSigBk\n");
+                          exit(1);
+                        }
+                        itypeSigBk[n][nkp]=kp;
+                      }
+                      cosAng_ikkp=(-dis_ik[0]*dis_kkp[0]-dis_ik[1]*dis_kkp[1]
+                          -dis_ik[2]*dis_kkp[2])/(r_ik*r_kkp); 
+                      dcA_ikkp[0][0]=(dis_kkp[0]*r_ik*r_kkp-cosAng_ikkp
+                          *-dis_ik[0]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[1][0]=(dis_kkp[1]*r_ik*r_kkp-cosAng_ikkp
+                          *-dis_ik[1]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[2][0]=(dis_kkp[2]*r_ik*r_kkp-cosAng_ikkp
+                          *-dis_ik[2]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[0][1]=(-dis_ik[0]*r_ik*r_kkp-cosAng_ikkp
+                          *dis_kkp[0]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[1][1]=(-dis_ik[1]*r_ik*r_kkp-cosAng_ikkp
+                          *dis_kkp[1]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[2][1]=(-dis_ik[2]*r_ik*r_kkp-cosAng_ikkp
+                          *dis_kkp[2]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+                      nb_kkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_kkp].temp=temp_kkp;
+                      bt_sg[nb_kkp].i=k;
+                      bt_sg[nb_kkp].j=kp;
+                      gmean0=sigma_g0[itype-1][ktype-1][kptype-1];          
+                      gmean1=sigma_g1[itype-1][ktype-1][kptype-1];          
+                      gmean2=sigma_g2[itype-1][ktype-1][kptype-1];          
+                      amean=cosAng_ikkp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS_ik*betaS_kkp;
+                      rfactor=rfactorrt*rfactorrt;
+
+//3rd CC is third term of Eq. 11 (c) for i atom 
+//where j , k =neighbor of i & k' =neighbor of k
+
+                      CC=CC+gfactor*rfactor;
+
+//agpdpr1 is derivative of CC 3rd term w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of CC 3rd term w.r.t. Beta(r_kk')
+//app1 is derivative of CC 3rd term w.r.t. cos(theta_jik)
+//app2 is derivative of CC 3rd term w.r.t. cos(theta_ikk')
+ 
+                      agpdpr1=2.0*gfactor*rfactorrt*betaS_kkp
+                          *dBetaS_ik/r_ik;
+                      agpdpr2=2.0*gfactor*rfactorrt*betaS_ik
+                          *dBetaS_kkp/r_kkp;
+                      app1=rfactor*gfactorsq2*gsqprime;
+                      app2=rfactor*gfactorsq*gsqprime2;
+                      bt_sg[nb_ij].dCC[0]+=
+                          app1*dcA_jik[0][0];
+                      bt_sg[nb_ij].dCC[1]+=
+                          app1*dcA_jik[1][0];
+                      bt_sg[nb_ij].dCC[2]+=
+                          app1*dcA_jik[2][0];
+                      bt_sg[nb_ik].dCC[0]+=
+                          app1*dcA_jik[0][1]
+                          +agpdpr1*dis_ik[0]
+                          -app2*dcA_ikkp[0][0];
+                      bt_sg[nb_ik].dCC[1]+=
+                          app1*dcA_jik[1][1]
+                          +agpdpr1*dis_ik[1]
+                          -app2*dcA_ikkp[1][0];
+                      bt_sg[nb_ik].dCC[2]+=
+                          app1*dcA_jik[2][1]
+                          +agpdpr1*dis_ik[2]
+                          -app2*dcA_ikkp[2][0];
+                      bt_sg[nb_kkp].dCC[0]+=
+                          app2*dcA_ikkp[0][1]
+                          +agpdpr2*dis_kkp[0];
+                      bt_sg[nb_kkp].dCC[1]+=
+                          app2*dcA_ikkp[1][1]
+                          +agpdpr2*dis_kkp[1];
+                      bt_sg[nb_kkp].dCC[2]+=
+                          app2*dcA_ikkp[2][1]
+                          +agpdpr2*dis_kkp[2];
+                    }
+                  }
+                }
+
+//j and k are different neighbors of i and k' is a neighbor j not equal to k
+
+                for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+                  sig_flag=0;
+                  temp_jkp=BOP_index[j]+ltmp;
+                  kp=jlist[ltmp];
+                  kptype = map[type[kp]]+1;
+                  kplist=firstneigh[kp];
+
+                  same_kkpk=0;
+                  same_jkpj=0;
+
+                  for(kpNeij=0;kpNeij<numneigh[kp];kpNeij++) {
+                    temp_kpj=BOP_index[kp]+kpNeij;
+                    kpj=kplist[kpNeij];
+                    if(x[j][0]==x[kpj][0]) {
+                      if(x[j][1]==x[kpj][1]) {
+                        if(x[j][2]==x[kpj][2]) {
+                          same_jkpj=1;
+                          break;
+                        }
+                      }
+                    }
+                  }
+                  for(kpNeik=0;kpNeik<numneigh[kp];kpNeik++) {
+                    temp_kpk=BOP_index[kp]+kpNeik;
+                    kpk=kplist[kpNeik];
+                    if(x[k][0]==x[kpk][0]) {
+                      if(x[k][1]==x[kpk][1]) {
+                        if(x[k][2]==x[kpk][2]) {
+                          same_kkpk=1;
+                          break;
+                        }
+                      }
+                    }
+                  }
+                  if(!same_jkpj&&!same_kkpk) {
+                    same_kkpk=0;
+                    for(kNeikp=0;kNeikp<numneigh[k];kNeikp++) {
+                      temp_kkp=BOP_index[k]+kNeikp;
+                      kkp=kplist[kNeikp];
+                      if(x[kp][0]==x[kkp][0]) {
+                        if(x[kp][1]==x[kkp][1]) {
+                          if(x[kp][2]==x[kkp][2]) {
+                            sig_flag=1;
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    if(sig_flag==1) {
+                      for(nsearch=0;nsearch<numneigh[kp];nsearch++) {
+                        kp_nsearch=BOP_index[kp]+nsearch;
+                        ncmp=kplist[nsearch];
+                        if(x[ncmp][0]==x[j][0]) {
+                          if(x[ncmp][1]==x[j][1]) {
+                            if(x[ncmp][2]==x[j][2]) {
+                              kpNeij=nsearch;
+                            }
+                          }
+                        }
+                        if(x[ncmp][0]==x[k][0]) {
+                          if(x[ncmp][1]==x[k][1]) {
+                            if(x[ncmp][2]==x[k][2]) {
+                              kpNeik=nsearch;
+                            }
+                          }
+                        }
+                      }
+                      if(jtype==kptype)
+                        ijkp=jtype-1;
+                      else if(jtype<kptype)
+                        ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+                      else
+                        ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+                      if(ktype==kptype)
+                        ikkp=ktype-1;
+                      else if(ktype<kptype)
+                        ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+                      else
+                        ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+ 
+                      dis_jkp[0]=x[kp][0]-x[j][0];
+                      dis_jkp[1]=x[kp][1]-x[j][1];
+                      dis_jkp[2]=x[kp][2]-x[j][2];
+                      rsq_jkp=dis_jkp[0]*dis_jkp[0]
+                          +dis_jkp[1]*dis_jkp[1]
+                          +dis_jkp[2]*dis_jkp[2];
+                      r_jkp=sqrtl(rsq_jkp);
+                      ps=r_jkp*rdr[ijkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+                          +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+                      dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+                          +pBetaS4[ijkp][ks-1];
+                      betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+                          +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+                      dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+                          +pBetaP4[ijkp][ks-1];
+                      dis_kkp[0]=x[kp][0]-x[k][0];
+                      dis_kkp[1]=x[kp][1]-x[k][1];
+                      dis_kkp[2]=x[kp][2]-x[k][2];
+                      rsq_kkp=dis_kkp[0]*dis_kkp[0]
+                          +dis_kkp[1]*dis_kkp[1]
+                          +dis_kkp[2]*dis_kkp[2];
+                      r_kkp=sqrtl(rsq_kkp);
+                      ps=r_kkp*rdr[ikkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+                          +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+                      dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+                          +pBetaS4[ikkp][ks-1];
+                      betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+                          +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+                      dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+                          +pBetaP4[ikkp][ks-1];
+                      cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+                          -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp);
+                      dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+                          *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+                          *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+                          *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+                          *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+                          *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+                          *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      cosAng_ikkp=(-dis_ik[0]*dis_kkp[0]-dis_ik[1]*dis_kkp[1]
+                          -dis_ik[2]*dis_kkp[2])/(r_ik*r_kkp);
+                      dcA_ikkp[0][0]=(dis_kkp[0]*r_ik*r_kkp-cosAng_ikkp
+                          *-dis_ik[0]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[1][0]=(dis_kkp[1]*r_ik*r_kkp-cosAng_ikkp
+                          *-dis_ik[1]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[2][0]=(dis_kkp[2]*r_ik*r_kkp-cosAng_ikkp
+                          *-dis_ik[2]*r_kkp*r_kkp)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[0][1]=(-dis_ik[0]*r_ik*r_kkp-cosAng_ikkp
+                          *dis_kkp[0]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[1][1]=(-dis_ik[1]*r_ik*r_kkp-cosAng_ikkp
+                          *dis_kkp[1]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+                      dcA_ikkp[2][1]=(-dis_ik[2]*r_ik*r_kkp-cosAng_ikkp
+                          *dis_kkp[2]*r_ik*r_ik)/(r_ik*r_ik*r_kkp*r_kkp);
+                      cosAng_jkpk=(dis_jkp[0]*dis_kkp[0]+dis_jkp[1]*dis_kkp[1]
+                          +dis_jkp[2]*dis_kkp[2])/(r_jkp*r_kkp);
+                      dcA_jkpk[0][0]=(-dis_kkp[0]*r_jkp*r_kkp-cosAng_jkpk
+                          *-dis_jkp[0]*r_kkp*r_kkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+                      dcA_jkpk[1][0]=(-dis_kkp[1]*r_jkp*r_kkp-cosAng_jkpk
+                          *-dis_jkp[1]*r_kkp*r_kkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+                      dcA_jkpk[2][0]=(-dis_kkp[2]*r_jkp*r_kkp-cosAng_jkpk
+                          *-dis_jkp[2]*r_kkp*r_kkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+                      dcA_jkpk[0][1]=(-dis_jkp[0]*r_jkp*r_kkp-cosAng_jkpk
+                          *-dis_kkp[0]*r_jkp*r_jkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+                      dcA_jkpk[1][1]=(-dis_jkp[1]*r_jkp*r_kkp-cosAng_jkpk
+                          *-dis_kkp[1]*r_jkp*r_jkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+                      dcA_jkpk[2][1]=(-dis_jkp[2]*r_jkp*r_kkp-cosAng_jkpk
+                          *-dis_kkp[2]*r_jkp*r_jkp)/(r_jkp*r_jkp*r_kkp*r_kkp);
+                      sig_flag=0;
+                      if(nSigBk[n]>neigh_ct) {
+                        printf("BOP 13:6 itypeSigBk error exit \n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              nkp=nsearch;
+                              sig_flag=1;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==0) {
+                        nSigBk[n]=nSigBk[n]+1;
+                        nkp=nSigBk[n]-1;
+                        if((nkp>=neigh_ct)) {
+                          printf("BOP 14:7 itypeSigBk error exit \n");
+                          exit(1);
+                        }
+                        itypeSigBk[n][nkp]=kp;
+                      }
+                      temp_kpk=BOP_index[kp]+kpNeik;
+                      nb_jkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_jkp].temp=temp_jkp;
+                      bt_sg[nb_jkp].i=j;
+                      bt_sg[nb_jkp].j=kp;
+                      nb_kkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_kkp].temp=temp_kkp;
+                      bt_sg[nb_kkp].i=k;
+                      bt_sg[nb_kkp].j=kp;
+                      gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+                      amean=cosAng_ijkp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[itype-1][ktype-1][kptype-1];
+                      gmean1=sigma_g1[itype-1][ktype-1][kptype-1];
+                      gmean2=sigma_g2[itype-1][ktype-1][kptype-1];
+                      amean=cosAng_ikkp;
+                      gfactor3=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[jtype-1][kptype-1][ktype-1];
+                      gmean1=sigma_g1[jtype-1][kptype-1][ktype-1];
+                      gmean2=sigma_g2[jtype-1][kptype-1][ktype-1];
+                      amean=cosAng_jkpk;
+                      gfactor4=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime4=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3*gfactor4;
+                      rfactor0=(betaS_ik+small2)*(betaS_jkp+small2)
+                          *(betaS_kkp+small2);
+                      rfactor=pow(rfactor0,2.0/3.0);
+                      drfactor=2.0/3.0*pow(rfactor0,-1.0/3.0);
+ 
+//EE is Eq. 25(notes)
+ 
+                      EE=EE+gfactor*rfactor;
+ 
+//agpdpr1 is derivative of agpdpr1 w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of agpdpr1 w.r.t. Beta(r_jk')
+//agpdpr3 is derivative of agpdpr1 w.r.t. Beta(r_kk')
+//app1 is derivative of agpdpr1 w.r.t. cos(theta_jik)
+//app2 is derivative of agpdpr1 w.r.t. cos(theta_ijk')
+//app3 is derivative of agpdpr1 w.r.t. cos(theta_ikk')
+//app4 is derivative of agpdpr1 w.r.t. cos(theta_jk'k)
+ 
+                      agpdpr1=gfactor*drfactor*(betaS_jkp+small2)*(betaS_kkp
+                          +small2)*dBetaS_ik/r_ik;
+                      agpdpr2=gfactor*drfactor*(betaS_ik+small2)*(betaS_kkp
+                          +small2)*dBetaS_jkp/r_jkp;
+                      agpdpr3=gfactor*drfactor*(betaS_ik+small2)*(betaS_jkp
+                          +small2)*dBetaS_kkp/r_kkp;
+                      app1=rfactor*gfactor2*gfactor3*gfactor4*gprime1;
+                      app2=rfactor*gfactor1*gfactor3*gfactor4*gprime2;
+                      app3=rfactor*gfactor1*gfactor2*gfactor4*gprime3;
+                      app4=rfactor*gfactor1*gfactor2*gfactor3*gprime4;
+                      bt_sg[nb_ij].dEE[0]+=
+                          app1*dcA_jik[0][0]
+                          -app2*dcA_ijkp[0][0];
+                      bt_sg[nb_ij].dEE[1]+=
+                          app1*dcA_jik[1][0]
+                          -app2*dcA_ijkp[1][0];
+                      bt_sg[nb_ij].dEE[2]+=
+                          app1*dcA_jik[2][0]
+                          -app2*dcA_ijkp[2][0];
+                      bt_sg[nb_ik].dEE[0]+=
+                          app1*dcA_jik[0][1]
+                          +agpdpr1*dis_ik[0]
+                          -app3*dcA_ikkp[0][0];
+                      bt_sg[nb_ik].dEE[1]+=
+                          app1*dcA_jik[1][1]
+                          +agpdpr1*dis_ik[1]
+                          -app3*dcA_ikkp[1][0];
+                      bt_sg[nb_ik].dEE[2]+=
+                          app1*dcA_jik[2][1]
+                          +agpdpr1*dis_ik[2]
+                          -app3*dcA_ikkp[2][0];
+                      bt_sg[nb_jkp].dEE[0]+=
+                          app2*dcA_ijkp[0][1]
+                          +agpdpr2*dis_jkp[0]
+                          -app4*dcA_jkpk[0][0];
+                      bt_sg[nb_jkp].dEE[1]+=
+                          app2*dcA_ijkp[1][1]
+                          +agpdpr2*dis_jkp[1]
+                          -app4*dcA_jkpk[1][0];
+                      bt_sg[nb_jkp].dEE[2]+=
+                          app2*dcA_ijkp[2][1]
+                          +agpdpr2*dis_jkp[2]
+                          -app4*dcA_jkpk[2][0];
+                      bt_sg[nb_kkp].dEE[0]+=
+                          app3*dcA_ikkp[0][1]
+                          +agpdpr3*dis_kkp[0]
+                          -app4*dcA_jkpk[0][1];
+                      bt_sg[nb_kkp].dEE[1]+=
+                          app3*dcA_ikkp[1][1]
+                          +agpdpr3*dis_kkp[1]
+                          -app4*dcA_jkpk[1][1];
+                      bt_sg[nb_kkp].dEE[2]+=
+                          app3*dcA_ikkp[2][1]
+                          +agpdpr3*dis_kkp[2]
+                          -app4*dcA_jkpk[2][1];
+                    }
+                  }
+                }
+              }
+            }
+          }
+        
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+          for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+            if(ktmp!=ji) {
+              temp_jk=BOP_index[j]+ktmp;
+              k=jlist[ktmp];
+              klist=firstneigh[k];
+              ktype=map[type[k]]+1;
+              for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                if(x[klist[kNeij]][0]==x[j][0]) {
+                  if(x[klist[kNeij]][1]==x[j][1]) {
+                    if(x[klist[kNeij]][2]==x[j][2]) {
+                      break;
+                    }
+                  }
+                }
+              }
+              if(jtype==ktype)
+                ijk=jtype-1;
+              else if(jtype<ktype)
+                ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+              else
+                ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+              sig_flag=0;
+              if((nSigBk[n]>neigh_ct)) {
+                printf("BOP 14:7 itypeSigBk error exit \n");
+                exit(1);
+              }
+              for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                ncmp=itypeSigBk[n][nsearch];
+                if(x[ncmp][0]==x[k][0]) {
+                  if(x[ncmp][1]==x[k][1]) {
+                    if(x[ncmp][2]==x[k][2]) {
+                      new1=nsearch;
+                      sig_flag=1;
+                      break;
+                    }
+                  }
+                }
+              }
+              if(sig_flag==0) {
+                nSigBk[n]=nSigBk[n]+1;
+                new1=nSigBk[n]-1;
+                if((new1>=neigh_ct)) {
+                  printf("BOP 14:7 itypeSigBk error exit \n");
+                  exit(1);
+                }
+                itypeSigBk[n][new1]=k;
+              }
+              dis_jk[0]=x[k][0]-x[j][0]; 
+              dis_jk[1]=x[k][1]-x[j][1]; 
+              dis_jk[2]=x[k][2]-x[j][2]; 
+              rsq_jk=dis_jk[0]*dis_jk[0]
+                  +dis_jk[1]*dis_jk[1]
+                  +dis_jk[2]*dis_jk[2];
+              r_jk=sqrt(rsq_jk); 
+              if(r_jk<=rcut[ijk]) {
+                ps=r_jk*rdr[ijk]+1.0;
+                ks=(int)ps;
+                if(nr-1<ks)
+                  ks=nr-1;
+                ps=ps-ks;
+                if(ps>1.0)
+                  ps=1.0;
+                betaS_jk=((pBetaS3[ijk][ks-1]*ps+pBetaS2[ijk][ks-1])*ps
+                    +pBetaS1[ijk][ks-1])*ps+pBetaS[ijk][ks-1];
+                dBetaS_jk=(pBetaS6[ijk][ks-1]*ps+pBetaS5[ijk][ks-1])*ps
+                    +pBetaS4[ijk][ks-1];
+                betaP_jk=((pBetaP3[ijk][ks-1]*ps+pBetaP2[ijk][ks-1])*ps
+                    +pBetaP1[ijk][ks-1])*ps+pBetaP[ijk][ks-1];
+                dBetaP_jk=(pBetaP6[ijk][ks-1]*ps+pBetaP5[ijk][ks-1])*ps
+                    +pBetaP4[ijk][ks-1];
+                cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+                    -dis_ij[2]*dis_jk[2])/(r_ij*r_jk); 
+                dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                amean=cosAng_ijk;
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gsqprime=2.0*gfactor1*gprime1;
+                rfactor1rt=betaS_jk*betaS_jk;
+                rfactor1=rfactor1rt*rfactor1rt;
+
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+
+                BB=BB+gfactorsq*rfactor1rt;
+                DD=DD+gfactorsq*rfactor1;
+
+//agpdpr1 is derivative of BB  w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+
+                agpdpr1=2.0*gfactorsq*betaS_jk*dBetaS_jk/r_jk;
+                agpdpr2=2.0*rfactor1rt*agpdpr1;
+                app1=rfactor1rt*gsqprime;
+                app2=rfactor1rt*app1;
+                bt_sg[nb_ij].dBB[0]-=
+                    app1*dcA_ijk[0][0];
+                bt_sg[nb_ij].dBB[1]-=
+                    app1*dcA_ijk[1][0];
+                bt_sg[nb_ij].dBB[2]-=
+                    app1*dcA_ijk[2][0];
+                bt_sg[nb_ij].dDD[0]-=
+                    app2*dcA_ijk[0][0];
+                bt_sg[nb_ij].dDD[1]-=
+                    app2*dcA_ijk[1][0];
+                bt_sg[nb_ij].dDD[2]-=
+                    app2*dcA_ijk[2][0];
+                bt_sg[nb_jk].dBB[0]+=
+                    app1*dcA_ijk[0][1]
+                    +agpdpr1*dis_jk[0];
+                bt_sg[nb_jk].dBB[1]+=
+                    app1*dcA_ijk[1][1]
+                    +agpdpr1*dis_jk[1];
+                bt_sg[nb_jk].dBB[2]+=
+                    app1*dcA_ijk[2][1]
+                    +agpdpr1*dis_jk[2];
+                bt_sg[nb_jk].dDD[0]+=
+                    app2*dcA_ijk[0][1]
+                    +agpdpr2*dis_jk[0];
+                bt_sg[nb_jk].dDD[1]+=
+                    app2*dcA_ijk[1][1]
+                    +agpdpr2*dis_jk[1];
+                bt_sg[nb_jk].dDD[2]+=
+                    app2*dcA_ijk[2][1]
+                    +agpdpr2*dis_jk[2];
+
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=ji) {
+                    temp_jkp=BOP_index[j]+ltmp;
+                    kp=jlist[ltmp];
+                    kptype=map[type[kp]]+1;
+                    if(jtype==kptype)
+                      ijkp=jtype-1;
+                    else if(jtype<kptype)
+                      ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+                    else
+                      ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+                    if((nSigBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                      ncmp=itypeSigBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            new2=nsearch;
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    dis_jkp[0]=x[kp][0]-x[j][0]; 
+                    dis_jkp[1]=x[kp][1]-x[j][1]; 
+                    dis_jkp[2]=x[kp][2]-x[j][2]; 
+                    rsq_jkp=dis_jkp[0]*dis_jkp[0]
+                        +dis_jkp[1]*dis_jkp[1]
+                        +dis_jkp[2]*dis_jkp[2];
+                    r_jkp=sqrt(rsq_jkp); 
+                    if(r_jkp<=rcut[ijkp]) {
+                      ps=r_jkp*rdr[ijkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+                        +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+                      dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+                        +pBetaS4[ijkp][ks-1];
+                      betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+                        +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+                      dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+                        +pBetaP4[ijkp][ks-1];
+                      cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+                        -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp); 
+                      dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+                        *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+                        *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+                        *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+                        *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+                        *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+                        *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      cosAng_kjkp=(dis_jk[0]*dis_jkp[0]+dis_jk[1]*dis_jkp[1]
+                        +dis_jk[2]*dis_jkp[2])/(r_jk*r_jkp); 
+                      dcA_kjkp[0][0]=(dis_jkp[0]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jk[0]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[1][0]=(dis_jkp[1]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jk[1]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[2][0]=(dis_jkp[2]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jk[2]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[0][1]=(dis_jk[0]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[1][1]=(dis_jk[1]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[2][1]=(dis_jk[2]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      nb_jkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_jkp].temp=temp_jkp;
+                      bt_sg[nb_jkp].i=j;
+                      bt_sg[nb_jkp].j=kp;
+                      gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+                      amean=cosAng_ijkp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+                      amean=cosAng_kjkp;
+                      gfactor3=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS_jk*betaS_jkp;
+                      rfactor=rfactorrt*rfactorrt;
+
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+
+                      DD=DD+2.0*gfactor*rfactor;
+
+//agpdpr1 is derivative of DD  w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD  w.r.t. Beta(r_jk')
+//app1 is derivative of DD  w.r.t. cos(theta_ijk)
+//app2 is derivative of DD  w.r.t. cos(theta_ijkp)
+//app3 is derivative of DD  w.r.t. cos(theta_kjkp)
+ 
+                      agpdpr1=4.0*gfactor*rfactorrt*betaS_jkp
+                          *dBetaS_jk/r_jk;
+                      agpdpr2=4.0*gfactor*rfactorrt*betaS_jk
+                          *dBetaS_jkp/r_jkp;
+                      app1=2.0*rfactor*gfactor2*gfactor3*gprime1;
+                      app2=2.0*rfactor*gfactor1*gfactor3*gprime2;
+                      app3=2.0*rfactor*gfactor1*gfactor2*gprime3;
+                      bt_sg[nb_ij].dDD[0]-=
+                          app1*dcA_ijk[0][0]
+                          +app2*dcA_ijkp[0][0];
+                      bt_sg[nb_ij].dDD[1]-=
+                          app1*dcA_ijk[1][0]
+                          +app2*dcA_ijkp[1][0];
+                      bt_sg[nb_ij].dDD[2]-=
+                          app1*dcA_ijk[2][0]
+                          +app2*dcA_ijkp[2][0];
+                      bt_sg[nb_jk].dDD[0]+=
+                          app1*dcA_ijk[0][1]
+                          +app3*dcA_kjkp[0][0]
+                          +agpdpr1*dis_jk[0];
+                      bt_sg[nb_jk].dDD[1]+=
+                          app1*dcA_ijk[1][1]
+                          +app3*dcA_kjkp[1][0]
+                          +agpdpr1*dis_jk[1];
+                      bt_sg[nb_jk].dDD[2]+=
+                          app1*dcA_ijk[2][1]
+                          +app3*dcA_kjkp[2][0]
+                          +agpdpr1*dis_jk[2];
+                      bt_sg[nb_jkp].dDD[0]+=
+                          app2*dcA_ijkp[0][1]
+                          +app3*dcA_kjkp[0][1]
+                          +agpdpr2*dis_jkp[0];
+                      bt_sg[nb_jkp].dDD[1]+=
+                          app2*dcA_ijkp[1][1]
+                          +app3*dcA_kjkp[1][1]
+                          +agpdpr2*dis_jkp[1];
+                      bt_sg[nb_jkp].dDD[2]+=
+                          app2*dcA_ijkp[2][1]
+                          +app3*dcA_kjkp[2][1]
+                          +agpdpr2*dis_jkp[2];
+
+                    }
+                  }
+                }
+
+//j is a neighbor of i, k is a neighbor of j not equal to i and k' 
+//is a neighbor of k not equal to j or i
+
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  kp=klist[ltmp];
+                  kptype=map[type[kp]]+1;
+                  same_ikp=0;
+                  same_jkp=0;
+                  if(x[i][0]==x[kp][0]) {
+                    if(x[i][1]==x[kp][1]) {
+                      if(x[i][2]==x[kp][2]) {
+                        same_ikp=1;
+                      }
+                    }
+                  }
+                  if(x[j][0]==x[kp][0]) {
+                    if(x[j][1]==x[kp][1]) {
+                      if(x[j][2]==x[kp][2]) {
+                        same_jkp=1;
+                      }
+                    }
+                  }
+                  if(!same_ikp&&!same_jkp) {
+                    if(ktype==kptype)
+                      ikkp=ktype-1;
+                    else if(ktype<kptype)
+                      ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+                    else
+                      ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+                    for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                      if(x[klist[kNeij]][0]==x[j][0]) {
+                        if(x[klist[kNeij]][1]==x[j][1]) {
+                          if(x[klist[kNeij]][2]==x[j][2]) {
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    sig_flag=0;
+                    if((nSigBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                      ncmp=itypeSigBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            new2=nsearch;
+                            sig_flag=1;
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    if(sig_flag==0) {
+                      nSigBk[n]=nSigBk[n]+1;
+                      new2=nSigBk[n]-1;
+                      if((new2>=neigh_ct)) {
+                        printf("BOP 14:7 itypeSigBk error exit \n");
+                        exit(1);
+                      }
+                      itypeSigBk[n][new2]=kp;
+                    }
+                    dis_kkp[0]=x[kp][0]-x[k][0]; 
+                    dis_kkp[1]=x[kp][1]-x[k][1]; 
+                    dis_kkp[2]=x[kp][2]-x[k][2]; 
+                    rsq_kkp=dis_kkp[0]*dis_kkp[0]
+                        +dis_kkp[1]*dis_kkp[1]
+                        +dis_kkp[2]*dis_kkp[2];
+                    r_kkp=sqrt(rsq_kkp); 
+                    if(r_kkp<=rcut[ikkp]) {
+                      ps=r_kkp*rdr[ikkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+                          +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+                      dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+                          +pBetaS4[ikkp][ks-1];
+                      betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+                          +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+                      dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+                          +pBetaP4[ikkp][ks-1];
+                      cosAng_jkkp=(-dis_jk[0]*dis_kkp[0]-dis_jk[1]*dis_kkp[1]
+                          -dis_jk[2]*dis_kkp[2])/(r_jk*r_kkp); 
+                      dcA_jkkp[0][0]=(dis_kkp[0]*r_jk*r_kkp-cosAng_jkkp
+                          *-dis_jk[0]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[1][0]=(dis_kkp[1]*r_jk*r_kkp-cosAng_jkkp
+                          *-dis_jk[1]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[2][0]=(dis_kkp[2]*r_jk*r_kkp-cosAng_jkkp
+                          *-dis_jk[2]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[0][1]=(-dis_jk[0]*r_jk*r_kkp-cosAng_jkkp
+                          *dis_kkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[1][1]=(-dis_jk[1]*r_jk*r_kkp-cosAng_jkkp
+                          *dis_kkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[2][1]=(-dis_jk[2]*r_jk*r_kkp-cosAng_jkkp
+                          *dis_kkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+                      nb_kkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_kkp].temp=temp_kkp;
+                      bt_sg[nb_kkp].i=k;
+                      bt_sg[nb_kkp].j=kp;
+                      gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+                      amean=cosAng_jkkp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS_jk*betaS_kkp;
+                      rfactor=rfactorrt*rfactorrt;
+
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+
+                      DD=DD+gfactor*rfactor;
+
+//agpdpr1 is derivative of DD  3rd term w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of DD  3rd term w.r.t. Beta(r_kk')
+//app1 is derivative of DD  3rd term w.r.t. cos(theta_ijk)
+//app2 is derivative of DD  3rd term w.r.t. cos(theta_jkkp)
+ 
+                      agpdpr1=2.0*gfactor*rfactorrt*betaS_kkp
+                          *dBetaS_jk/r_jk;
+                      agpdpr2=2.0*gfactor*rfactorrt*betaS_jk
+                          *dBetaS_kkp/r_kkp;
+                      app1=rfactor*gfactorsq2*gsqprime;
+                      app2=rfactor*gfactorsq*gsqprime2;
+                      bt_sg[nb_ij].dDD[0]-=
+                          app1*dcA_ijk[0][0];
+                      bt_sg[nb_ij].dDD[1]-=
+                          app1*dcA_ijk[1][0];
+                      bt_sg[nb_ij].dDD[2]-=
+                          app1*dcA_ijk[2][0];
+                      bt_sg[nb_jk].dDD[0]+=
+                          app1*dcA_ijk[0][1]
+                          +agpdpr1*dis_jk[0]
+                          -app2*dcA_jkkp[0][0];
+                      bt_sg[nb_jk].dDD[1]+=
+                          app1*dcA_ijk[1][1]
+                          +agpdpr1*dis_jk[1]
+                          -app2*dcA_jkkp[1][0];
+                      bt_sg[nb_jk].dDD[2]+=
+                          app1*dcA_ijk[2][1]
+                          +agpdpr1*dis_jk[2]
+                          -app2*dcA_jkkp[2][0];
+                      bt_sg[nb_kkp].dDD[0]+=
+                          app2*dcA_jkkp[0][1]
+                          +agpdpr2*dis_kkp[0];
+                      bt_sg[nb_kkp].dDD[1]+=
+                          app2*dcA_jkkp[1][1]
+                          +agpdpr2*dis_kkp[1];
+                      bt_sg[nb_kkp].dDD[2]+=
+                          app2*dcA_jkkp[2][1]
+                          +agpdpr2*dis_kkp[2];
+
+                    }
+                  }
+                }
+              }
+            }
+          }
+
+          sig_flag=0;
+          if(FF<=0.000001) {
+            sigB[n]=0.0;
+            sig_flag=1;
+          }
+          if(sig_flag==0) {
+            if(AA<0.0)
+              AA=0.0;
+            if(BB<0.0)
+              BB=0.0;
+            if(CC<0.0)
+              CC=0.0;
+            if(DD<0.0)
+              DD=0.0;
+
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+
+            AAC=AA+BB;
+            BBC=AA*BB;
+            CCC=AA*AA+BB*BB;
+            DDC=CC+DD;
+
+//EEC is a modified form of (a) Eq. 33
+
+            EEC=(DDC-CCC)/(AAC+2.0*small1);
+            AACFF=1.0/(AAC+2.0*small1);
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+                    +bt_sg[m].dBB[0];
+                bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+                    +bt_sg[m].dBB[1];
+                bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+                    +bt_sg[m].dBB[2];
+                bt_sg[m].dBBC[0]=bt_sg[m].dAA[0]*BB
+                    +AA*bt_sg[m].dBB[0];
+                bt_sg[m].dBBC[1]=bt_sg[m].dAA[1]*BB
+                    +AA*bt_sg[m].dBB[1];
+                bt_sg[m].dBBC[2]=bt_sg[m].dAA[2]*BB
+                    +AA*bt_sg[m].dBB[2];
+                bt_sg[m].dCCC[0]=2.0*AA*bt_sg[m].dAA[0]
+                    +2.0*BB*bt_sg[m].dBB[0];
+                bt_sg[m].dCCC[1]=2.0*AA*bt_sg[m].dAA[1]
+                    +2.0*BB*bt_sg[m].dBB[1];
+                bt_sg[m].dCCC[2]=2.0*AA*bt_sg[m].dAA[2]
+                    +2.0*BB*bt_sg[m].dBB[2];
+                bt_sg[m].dDDC[0]=bt_sg[m].dCC[0]
+                    +bt_sg[m].dDD[0];
+                bt_sg[m].dDDC[1]=bt_sg[m].dCC[1]
+                    +bt_sg[m].dDD[1];
+                bt_sg[m].dDDC[2]=bt_sg[m].dCC[2]
+                    +bt_sg[m].dDD[2];
+                bt_sg[m].dEEC[0]=(bt_sg[m].dDDC[0]
+                    -bt_sg[m].dCCC[0]
+                    -EEC*bt_sg[m].dAAC[0])*AACFF;
+                bt_sg[m].dEEC[1]=(bt_sg[m].dDDC[1]
+                    -bt_sg[m].dCCC[1]
+                    -EEC*bt_sg[m].dAAC[1])*AACFF;
+                bt_sg[m].dEEC[2]=(bt_sg[m].dDDC[2]
+                    -bt_sg[m].dCCC[2]
+                    -EEC*bt_sg[m].dAAC[2])*AACFF;
+              } 
+            }
+            UT=EEC*FF+BBC+small3[iij];
+            UT=1.0/sqrt(UT);
+
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+
+            FFC=BBC*UT;
+            GGC=EEC*UT;
+            bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])*(1.0+sigma_a[iij]*GGC)
+                *(1.0+sigma_a[iij]*GGC)+sigma_c[iij]*(AAC+sigma_a[iij]*EE
+                +sigma_a[iij]*FFC*(2.0+GGC))+small4;
+            UTcom=-0.5*UT*UT*UT;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                bt_sg[m].dUT[0]=UTcom*(bt_sg[m].dEEC[0]*FF
+                    +EEC*bt_sg[m].dFF[0]+bt_sg[m].dBBC[0]);
+                bt_sg[m].dUT[1]=UTcom*(bt_sg[m].dEEC[1]*FF
+                    +EEC*bt_sg[m].dFF[1]+bt_sg[m].dBBC[1]);
+                bt_sg[m].dUT[2]=UTcom*(bt_sg[m].dEEC[2]*FF
+                    +EEC*bt_sg[m].dFF[2]+bt_sg[m].dBBC[2]);
+                bt_sg[m].dFFC[0]=bt_sg[m].dBBC[0]*UT
+                    +BBC*bt_sg[m].dUT[0];
+                bt_sg[m].dFFC[1]=bt_sg[m].dBBC[1]*UT
+                    +BBC*bt_sg[m].dUT[1];
+                bt_sg[m].dFFC[2]=bt_sg[m].dBBC[2]*UT
+                    +BBC*bt_sg[m].dUT[2];
+                bt_sg[m].dGGC[0]=bt_sg[m].dEEC[0]*UT
+                    +EEC*bt_sg[m].dUT[0];
+                bt_sg[m].dGGC[1]=bt_sg[m].dEEC[1]*UT
+                    +EEC*bt_sg[m].dUT[1];
+                bt_sg[m].dGGC[2]=bt_sg[m].dEEC[2]*UT
+                    +EEC*bt_sg[m].dUT[2];
+              }
+            }
+            psign=1.0;
+            if(1.0+sigma_a[iij]*GGC<0.0)
+              psign=-1.0;
+            bndtmp0=1.0/sqrtl(bndtmp);
+            sigB1[n]=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)*bndtmp0;
+            bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+            bndtmp1=psign*(1.0+sigma_a[iij]*GGC)*bndtmp0+psign*betaS_ij
+                *(1.0+sigma_a[iij]*GGC)*bndtmp*2.0*betaS_ij*(1.0
+                +sigma_a[iij]*GGC)*(1.0+sigma_a[iij]*GGC);
+            bndtmp1=bndtmp1*dBetaS_ij/r_ij;
+            bndtmp2=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)*bndtmp*sigma_c[iij];
+            bndtmp3=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)
+                *bndtmp*sigma_c[iij]*sigma_a[iij];
+            bndtmp4=psign*betaS_ij*(1.0+sigma_a[iij]*GGC)
+                *bndtmp*sigma_c[iij]*sigma_a[iij]*(2.0+GGC);
+            bndtmp5=sigma_a[iij]*psign*betaS_ij*bndtmp0
+                +psign*betaS_ij*(1.0+sigma_a[iij]*GGC)*bndtmp
+                *(2.0*(FF+sigma_delta[iij]*sigma_delta[iij])*(1.0
+                +sigma_a[iij]*GGC)*sigma_a[iij]+sigma_c[iij]*sigma_a[iij]*FFC);
+            setting=0;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                if(temp_kk==temp_ij&&setting==0) {
+                  bt_sg[m].dSigB1[0]=bndtmp1*dis_ij[0]
+                      +(bndtmp2*bt_sg[m].dAAC[0]
+                      +bndtmp3*bt_sg[m].dEE[0]
+                      +bndtmp4*bt_sg[m].dFFC[0]
+                      +bndtmp5*bt_sg[m].dGGC[0]);
+                  bt_sg[m].dSigB1[1]=bndtmp1*dis_ij[1]
+                      +(bndtmp2*bt_sg[m].dAAC[1]
+                      +bndtmp3*bt_sg[m].dEE[1]
+                      +bndtmp4*bt_sg[m].dFFC[1]
+                      +bndtmp5*bt_sg[m].dGGC[1]);
+                  bt_sg[m].dSigB1[2]=bndtmp1*dis_ij[2]
+                      +(bndtmp2*bt_sg[m].dAAC[2]
+                      +bndtmp3*bt_sg[m].dEE[2]
+                      +bndtmp4*bt_sg[m].dFFC[2]
+                      +bndtmp5*bt_sg[m].dGGC[2]);
+                  setting=1;
+                }
+                else if(temp_kk==temp_ji&&setting==0) {
+                  bt_sg[m].dSigB1[0]=-bndtmp1*dis_ij[0]
+                      +(bndtmp2*bt_sg[m].dAAC[0]
+                      +bndtmp3*bt_sg[m].dEE[0]
+                      +bndtmp4*bt_sg[m].dFFC[0]
+                      +bndtmp5*bt_sg[m].dGGC[0]);
+                  bt_sg[m].dSigB1[1]=-bndtmp1*dis_ij[1]
+                      +(bndtmp2*bt_sg[m].dAAC[1]
+                      +bndtmp3*bt_sg[m].dEE[1]
+                      +bndtmp4*bt_sg[m].dFFC[1]
+                      +bndtmp5*bt_sg[m].dGGC[1]);
+                  bt_sg[m].dSigB1[2]=-bndtmp1*dis_ij[2]
+                      +(bndtmp2*bt_sg[m].dAAC[2]
+                      +bndtmp3*bt_sg[m].dEE[2]
+                      +bndtmp4*bt_sg[m].dFFC[2]
+                      +bndtmp5*bt_sg[m].dGGC[2]);
+                  setting=1;
+                }
+                else {
+                  bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]
+                      +bndtmp3*bt_sg[m].dEE[0]
+                      +bndtmp4*bt_sg[m].dFFC[0]
+                      +bndtmp5*bt_sg[m].dGGC[0]);
+                  bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]
+                      +bndtmp3*bt_sg[m].dEE[1]
+                      +bndtmp4*bt_sg[m].dFFC[1]
+                      +bndtmp5*bt_sg[m].dGGC[1]);
+                  bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]
+                      +bndtmp3*bt_sg[m].dEE[2]
+                      +bndtmp4*bt_sg[m].dFFC[2]
+                      +bndtmp5*bt_sg[m].dGGC[2]);
+                }
+              }
+            }
+
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+
+            if(nb_t==0) {
+              if(j>i) {
+                bt_sg[0].dSigB1[0]=bndtmp1*dis_ij[0];
+                bt_sg[0].dSigB1[1]=bndtmp1*dis_ij[1];
+                bt_sg[0].dSigB1[2]=bndtmp1*dis_ij[2];
+              }
+              else {
+                bt_sg[0].dSigB1[0]=-bndtmp1*dis_ij[0];
+                bt_sg[0].dSigB1[1]=-bndtmp1*dis_ij[1];
+                bt_sg[0].dSigB1[2]=-bndtmp1*dis_ij[2];
+              }
+              for(pp=0;pp<3;pp++) {
+                bt_sg[0].dAA[pp]=0.0;
+                bt_sg[0].dBB[pp]=0.0;
+                bt_sg[0].dCC[pp]=0.0;
+                bt_sg[0].dDD[pp]=0.0;
+                bt_sg[0].dEE[pp]=0.0;
+                bt_sg[0].dEE1[pp]=0.0;
+                bt_sg[0].dFF[pp]=0.0;
+                bt_sg[0].dAAC[pp]=0.0;
+                bt_sg[0].dBBC[pp]=0.0;
+                bt_sg[0].dCCC[pp]=0.0;
+                bt_sg[0].dDDC[pp]=0.0;
+                bt_sg[0].dEEC[pp]=0.0;
+                bt_sg[0].dFFC[pp]=0.0;
+                bt_sg[0].dGGC[pp]=0.0;
+                bt_sg[0].dUT[pp]=0.0;
+                bt_sg[0].dSigB1[pp]=0.0;
+                bt_sg[0].dSigB[pp]=0.0;
+              }
+              bt_sg[0].i=i;
+              bt_sg[0].j=j;
+              bt_sg[0].temp=temp_ij;
+              nb_t++;
+              if(nb_t>nb_sg) {
+                new_n_tot=nb_sg+maxneigh;
+                grow_sigma(nb_sg,new_n_tot);
+                nb_sg=new_n_tot;
+              }
+            }
+            ps=sigB1[n]*rdBO+1.0;
+            ks=(int)ps;
+            if(nBOt-1<ks)
+              ks=nBOt-1;
+            ps=ps-ks;
+            if(ps>1.0)
+              ps=1.0;
+            dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+                +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+            dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+            part0=(FF+0.5*AAC+small5);
+            part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+            part2=1.0-part1*EE1/part0;
+            part3=dsigB1*part1/part0;
+            part4=part3/part0*EE1;
+
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+
+            sigB[n]=dsigB1*part2;
+            pp1=2.0*betaS_ij;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                bt_i=bt_sg[m].i;
+                bt_j=bt_sg[m].j;
+                xtmp[0]=x[bt_j][0]-x[bt_i][0];
+                xtmp[1]=x[bt_j][1]-x[bt_i][1];
+                xtmp[2]=x[bt_j][2]-x[bt_i][2];
+                for(pp=0;pp<3;pp++) {
+                  bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+                      -part3*bt_sg[m].dEE1[pp]
+                      +part4*(bt_sg[m].dFF[pp]
+                      +0.5*bt_sg[m].dAAC[pp]);
+                }
+                for(pp=0;pp<3;pp++) {
+                  ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+                  f[bt_i][pp]-=ftmp[pp];
+                  f[bt_j][pp]+=ftmp[pp];
+                }
+                if(evflag) {
+                  ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                      ,ftmp[2],xtmp[0],xtmp[1],xtmp[2]);
+                }
+              }
+            }
+          }
+          n++;
+        }
+      }
+    }
+  }
+  destroy_sigma();
+}
+
+/*  The formulation differs slightly to avoid negative square roots
+    in the calculation of Theta_pi,ij of (a) Eq. 36 and (b) Eq. 18 
+    see (d) */
+ 
+void PairBOP::sigmaBo_noa_otf()
+{
+  int nb_t,new_n_tot;
+  int n,i,j,k,kp,m,pp;
+  int itmp,jtmp,ktmp,ltmp,mtmp;
+  int i_tag,j_tag;
+  int kp1,kp2,kp1type;
+  int iij,iik,ijk,ikkp,ji,iikp,ijkp;
+  int nkp;
+  int nk0;
+  int jNeik,kNeii,kNeij;
+  int new1,new2,nlocal;
+  int inum,*ilist,*iilist,*jlist,*klist;
+  int **firstneigh,*numneigh; 
+  int temp_ij,temp_ik,temp_jkp,temp_kk,temp_jk;
+  int temp_ji,temp_kkp;
+  int temp_kpk;
+  int nb_ij,nb_ik,nb_ikp;
+  int nb_jk,nb_jkp,nb_kkp;
+  int kp_nsearch,nsearch;
+  int sig_flag,setting,ncmp,ks;
+  int itype,jtype,ktype,kptype;
+  int bt_i,bt_j,bt_ij;
+  int kp_index,same_ikp,same_jkp,same_kpk;
+  double AA,BB,CC,DD,EE,EE1,FF;
+  double AAC,BBC,CCC,DDC,EEC,FFC,GGC;
+  double AACFF,UT,bndtmp,UTcom;
+  double amean,gmean0,gmean1,gmean2,ps;
+  double gfactor1,gprime1,gsqprime,factorsq;
+  double gfactorsq,gfactor2,gprime2;
+  double gfactorsq2,gsqprime2;
+  double gfactor3,gprime3,gfactor,rfactor;
+  double drfactor,gfactor4,gprime4,agpdpr3;
+  double rfactor0,rfactorrt,rfactor1rt,rfactor1;
+  double rcm1,rcm2,gcm1,gcm2,gcm3;
+  double agpdpr1,agpdpr2,app1,app2,app3,app4;
+  double dsigB1,dsigB2;
+  double part0,part1,part2,part3,part4;
+  double psign,bndtmp0,pp1;
+  double bndtmp1,bndtmp2;
+  double dis_ij[3],rsq_ij,r_ij;
+  double betaS_ij,dBetaS_ij;
+  double betaP_ij,dBetaP_ij;
+  double dis_ik[3],rsq_ik,r_ik;
+  double betaS_ik,dBetaS_ik;
+  double betaP_ik,dBetaP_ik;
+  double dis_ikp[3],rsq_ikp,r_ikp;
+  double betaS_ikp,dBetaS_ikp;
+  double betaP_ikp,dBetaP_ikp;
+  double dis_jk[3],rsq_jk,r_jk;
+  double betaS_jk,dBetaS_jk;
+  double betaP_jk,dBetaP_jk;
+  double dis_jkp[3],rsq_jkp,r_jkp;
+  double betaS_jkp,dBetaS_jkp;
+  double betaP_jkp,dBetaP_jkp;
+  double dis_kkp[3],rsq_kkp,r_kkp;
+  double betaS_kkp,dBetaS_kkp;
+  double betaP_kkp,dBetaP_kkp;
+  double cosAng_jik,dcA_jik[3][2];
+  double cosAng_jikp,dcA_jikp[3][2];
+  double cosAng_kikp,dcA_kikp[3][2];
+  double cosAng_ijk,dcA_ijk[3][2];
+  double cosAng_ijkp,dcA_ijkp[3][2];
+  double cosAng_kjkp,dcA_kjkp[3][2];
+  double cosAng_ikj,dcA_ikj[3][2];
+  double cosAng_ikkp,dcA_ikkp[3][2];
+  double cosAng_jkkp,dcA_jkkp[3][2];
+  double cosAng_jkpk,dcA_jkpk[3][2];
+ 
+ 
+  double ftmp[3],xtmp[3];
+  double **x = atom->x;
+  double **f = atom->f;
+  int *tag = atom->tag;
+  int newton_pair = force->newton_pair;
+  int *type = atom->type;
+
+  nlocal = atom->nlocal;
+  int nall = nlocal + atom->nghost;
+  inum = list->inum; 
+  ilist = list->ilist;
+  numneigh = list->numneigh;
+  firstneigh = list->firstneigh;
+
+  n=0;
+  if(nb_sg==0) {
+    nb_sg=4;
+  }
+  if(allocate_sigma) {
+    destroy_sigma();
+  }
+    create_sigma(nb_sg);
+  for(itmp=0;itmp<inum;itmp++) {
+ 
+    i = ilist[itmp];
+    i_tag=tag[i];  
+    itype = map[type[i]]+1;
+
+//j is loop over all neighbors of i
+ 
+    if(numneigh[i]>maxneigh) {
+      printf("split neighbor error!\n");
+      exit(1);
+    } 
+    for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+      for(m=0;m<nb_sg;m++) {
+        for(pp=0;pp<3;pp++) {
+          bt_sg[m].dAA[pp]=0.0;
+          bt_sg[m].dBB[pp]=0.0;
+          bt_sg[m].dEE1[pp]=0.0;
+          bt_sg[m].dFF[pp]=0.0;
+          bt_sg[m].dAAC[pp]=0.0;
+          bt_sg[m].dSigB1[pp]=0.0;
+          bt_sg[m].dSigB[pp]=0.0;
+        }
+        bt_sg[m].i=-1;
+        bt_sg[m].j=-1;
+      }
+      nb_t=0;
+      iilist=firstneigh[i];
+      temp_ij=BOP_index[i]+jtmp;
+      j=iilist[jtmp];
+      jlist=firstneigh[j];
+      j_tag=tag[j];
+      jtype = map[type[j]]+1;
+      nb_ij=nb_t;
+      nb_t++;
+      if(nb_t>nb_sg) {
+        new_n_tot=nb_sg+maxneigh;
+        grow_sigma(nb_sg,new_n_tot);
+        nb_sg=new_n_tot;
+      }
+      bt_sg[nb_ij].temp=temp_ij;
+      bt_sg[nb_ij].i=i;
+      bt_sg[nb_ij].j=j;
+      if(j_tag>=i_tag) {
+        if(n>=neigh_total) {
+          printf("BOP 16:n is too large \n");
+          exit(1);
+        }
+        if(itype==jtype)
+          iij=itype-1;
+        else if(itype<jtype)
+          iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+        else
+          iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+        for(ji=0;ji<numneigh[j];ji++) {
+          temp_ji=BOP_index[j]+ji;
+          if(x[jlist[ji]][0]==x[i][0]) {
+            if(x[jlist[ji]][1]==x[i][1]) {
+              if(x[jlist[ji]][2]==x[i][2]) {
+                break;
+              }
+            }
+          }
+        }
+        dis_ij[0]=x[j][0]-x[i][0]; 
+        dis_ij[1]=x[j][1]-x[i][1]; 
+        dis_ij[2]=x[j][2]-x[i][2]; 
+        rsq_ij=dis_ij[0]*dis_ij[0]
+            +dis_ij[1]*dis_ij[1]
+            +dis_ij[2]*dis_ij[2];
+        r_ij=sqrt(rsq_ij); 
+ 
+        if(r_ij<rcut[iij]) {
+ 
+          ps=r_ij*rdr[iij]+1.0;
+          ks=(int)ps;
+          if(nr-1<ks)
+            ks=nr-1;
+          ps=ps-ks;
+          if(ps>1.0)
+            ps=1.0;
+          betaS_ij=((pBetaS3[iij][ks-1]*ps+pBetaS2[iij][ks-1])*ps
+              +pBetaS1[iij][ks-1])*ps+pBetaS[iij][ks-1];
+          dBetaS_ij=(pBetaS6[iij][ks-1]*ps+pBetaS5[iij][ks-1])*ps
+              +pBetaS4[iij][ks-1];
+          betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+              +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+          dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+              +pBetaP4[iij][ks-1];
+          nSigBk[n]=0;
+ 
+//AA-EE1 are the components making up Eq. 30 (a)
+ 
+          AA=0.0;
+          BB=0.0;
+          CC=0.0;
+          DD=0.0;
+          EE=0.0;
+          EE1=0.0;
+ 
+//FF is the Beta_sigma^2 term
+       
+          FF=betaS_ij*betaS_ij;
+ 
+//agpdpr1 is derivative of FF w.r.t. r_ij
+ 
+          agpdpr1=2.0*betaS_ij*dBetaS_ij/r_ij;
+ 
+//dXX derivatives are taken with respect to all pairs contributing to the energy
+//nb_ij is derivative w.r.t. ij pair
+ 
+          bt_sg[nb_ij].dFF[0]=agpdpr1*dis_ij[0];
+          bt_sg[nb_ij].dFF[1]=agpdpr1*dis_ij[1];
+          bt_sg[nb_ij].dFF[2]=agpdpr1*dis_ij[2];
+ 
+//k is loop over all neighbors of i again with j neighbor of i 
+ 
+          for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+            temp_ik=BOP_index[i]+ktmp;
+            if(ktmp!=jtmp) {
+              k=iilist[ktmp];
+              klist=firstneigh[k];
+              ktype = map[type[k]]+1;
+              if(itype==ktype)
+                iik=itype-1;
+              else if(itype<ktype)
+                iik=itype*bop_types-itype*(itype+1)/2+ktype-1;
+              else
+                iik=ktype*bop_types-ktype*(ktype+1)/2+itype-1;
+  
+//find neighbor of k that is equal to i
+ 
+              for(kNeii=0;kNeii<numneigh[k];kNeii++) {
+                if(x[klist[kNeii]][0]==x[i][0]) {
+                  if(x[klist[kNeii]][1]==x[i][1]) {
+                    if(x[klist[kNeii]][2]==x[i][2]) {
+                      break;
+                    }
+                  }
+                }
+              }
+              dis_ik[0]=x[k][0]-x[i][0]; 
+              dis_ik[1]=x[k][1]-x[i][1]; 
+              dis_ik[2]=x[k][2]-x[i][2]; 
+              rsq_ik=dis_ik[0]*dis_ik[0]
+                  +dis_ik[1]*dis_ik[1]
+                  +dis_ik[2]*dis_ik[2];
+              r_ik=sqrt(rsq_ik); 
+              if(r_ik<=rcut[iik]) {
+                ps=r_ik*rdr[iik]+1.0;
+                ks=(int)ps;
+                if(nr-1<ks)
+                  ks=nr-1;
+                ps=ps-ks;
+                if(ps>1.0)
+                  ps=1.0;
+                betaS_ik=((pBetaS3[iik][ks-1]*ps+pBetaS2[iik][ks-1])*ps
+                    +pBetaS1[iik][ks-1])*ps+pBetaS[iik][ks-1];
+                dBetaS_ik=(pBetaS6[iik][ks-1]*ps+pBetaS5[iik][ks-1])*ps
+                    +pBetaS4[iik][ks-1];
+                betaP_ik=((pBetaP3[iik][ks-1]*ps+pBetaP2[iik][ks-1])*ps
+                    +pBetaP1[iik][ks-1])*ps+pBetaP[iik][ks-1];
+                dBetaP_ik=(pBetaP6[iik][ks-1]*ps+pBetaP5[iik][ks-1])*ps
+                    +pBetaP4[iik][ks-1];
+ 
+//find neighbor of i that is equal to k
+ 
+                for(jNeik=0;jNeik<numneigh[j];jNeik++) {
+                  temp_jk=BOP_index[j]+jNeik;
+                  if(x[jlist[jNeik]][0]==x[k][0]) {
+                    if(x[jlist[jNeik]][1]==x[k][1]) {
+                      if(x[jlist[jNeik]][2]==x[k][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+ 
+//find neighbor of k that is equal to j
+ 
+                for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                  if(x[klist[kNeij]][0]==x[j][0]) {
+                    if(x[klist[kNeij]][1]==x[j][1]) {
+                      if(x[klist[kNeij]][2]==x[j][2]) {
+                        break;
+                      }
+                    }
+                  }
+                }
+                dis_jk[0]=x[k][0]-x[j][0]; 
+                dis_jk[1]=x[k][1]-x[j][1]; 
+                dis_jk[2]=x[k][2]-x[j][2]; 
+                rsq_jk=dis_jk[0]*dis_jk[0]
+                    +dis_jk[1]*dis_jk[1]
+                    +dis_jk[2]*dis_jk[2];
+                r_jk=sqrt(rsq_jk); 
+ 
+                sig_flag=0;
+                if((nSigBk[n]>neigh_ct)) {
+                  printf("BOP 14:7 itypeSigBk error exit \n");
+                  exit(1);
+                }
+                for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                  ncmp=itypeSigBk[n][nsearch];
+                  if(x[ncmp][0]==x[k][0]) {
+                    if(x[ncmp][1]==x[k][1]) {
+                      if(x[ncmp][2]==x[k][2]) {
+                        nk0=nsearch;
+                        sig_flag=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(sig_flag==0) {
+                  nSigBk[n]=nSigBk[n]+1;
+                  nk0=nSigBk[n]-1;
+                  if((nk0>=neigh_ct)) {
+                    printf("BOP 14:7 itypeSigBk error exit \n");
+                    exit(1);
+                  }
+                  itypeSigBk[n][nk0]=k;
+                }
+                nb_ik=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_ik].temp=temp_ik;
+                bt_sg[nb_ik].i=i;
+                bt_sg[nb_ik].j=k;
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                cosAng_jik=(dis_ij[0]*dis_ik[0]+dis_ij[1]*dis_ik[1]
+                    +dis_ij[2]*dis_ik[2])/(r_ij*r_ik); 
+                dcA_jik[0][0]=(dis_ik[0]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[0]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[1][0]=(dis_ik[1]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[1]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[2][0]=(dis_ik[2]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[2]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[0][1]=(dis_ij[0]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[0]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[1][1]=(dis_ij[1]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[1]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[2][1]=(dis_ij[2]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[2]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                gmean0=sigma_g0[jtype-1][itype-1][ktype-1];
+                gmean1=sigma_g1[jtype-1][itype-1][ktype-1];
+                gmean2=sigma_g2[jtype-1][itype-1][ktype-1];
+                amean=cosAng_jik;
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gsqprime=2.0*gfactor1*gprime1;
+ 
+//AA is Eq. 34 (a) or Eq. 10 (c) for the i atom
+//1st CC is Eq. 11 (c) for i atom where j & k=neighbor of i
+ 
+                AA=AA+gfactorsq*betaS_ik*betaS_ik;
+                CC=CC+gfactorsq*betaS_ik*betaS_ik*betaS_ik*betaS_ik;
+ 
+//agpdpr1 is derivative of AA w.r.t. Beta(rik)
+//app1 is derivative of AA w.r.t. cos(theta_jik)
+ 
+                agpdpr1=2.0*gfactorsq*betaS_ik*dBetaS_ik/r_ik;
+                app1=betaS_ik*betaS_ik*gsqprime;
+                bt_sg[nb_ij].dAA[0]+=
+                    app1*dcA_jik[0][0];
+                bt_sg[nb_ij].dAA[1]+=
+                    app1*dcA_jik[1][0];
+                bt_sg[nb_ij].dAA[2]+=
+                    app1*dcA_jik[2][0];
+                bt_sg[nb_ik].dAA[0]+=
+                    app1*dcA_jik[0][1]
+                    +agpdpr1*dis_ik[0];
+                bt_sg[nb_ik].dAA[1]+=
+                    app1*dcA_jik[1][1]
+                    +agpdpr1*dis_ik[1];
+                bt_sg[nb_ik].dAA[2]+=
+                    app1*dcA_jik[2][1]
+                    +agpdpr1*dis_ik[2];
+ 
+//k' is loop over neighbors all neighbors of j with k a neighbor
+//of i and j a neighbor of i and determine which k' is k 
+                
+                same_kpk=0; 
+                for(ltmp=0;ltmp<numneigh[j];ltmp++) {
+                  temp_jkp=BOP_index[j]+ltmp;
+                  kp1=jlist[ltmp];
+                  kp1type=map[type[kp1]]+1;
+                  if(x[kp1][0]==x[k][0]) {
+                    if(x[kp1][1]==x[k][1]) {
+                      if(x[kp1][2]==x[k][2]) {
+                        same_kpk=1;
+                        break;
+                      }
+                    }
+                  }
+                }
+                if(same_kpk){
+ 
+//loop over neighbors of k
+ 
+                  for(mtmp=0;mtmp<numneigh[k];mtmp++) {
+                    kp2=klist[mtmp];
+                    if(x[kp2][0]==x[k][0]) {
+                      if(x[kp2][1]==x[k][1]) {
+                        if(x[kp2][2]==x[k][2]) {
+                          break;
+                        }
+                      }
+                    }
+                  }
+                  if(jtype==ktype)
+                    ijk=jtype-1;
+                  else if(jtype < ktype)
+                    ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+                  else
+                    ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+                  if(jtype==kp1type)
+                    ijkp=jtype-1;
+                  else if(jtype<kp1type)
+                    ijkp=jtype*bop_types-jtype*(jtype+1)/2+kp1type-1;
+                  else
+                    ijkp=kp1type*bop_types-kp1type*(kp1type+1)/2+jtype-1;
+ 
+                  dis_jkp[0]=x[kp1][0]-x[j][0]; 
+                  dis_jkp[1]=x[kp1][1]-x[j][1]; 
+                  dis_jkp[2]=x[kp1][2]-x[j][2]; 
+                  rsq_jkp=dis_jkp[0]*dis_jkp[0]
+                      +dis_jkp[1]*dis_jkp[1]
+                      +dis_jkp[2]*dis_jkp[2];
+                  r_jkp=sqrt(rsq_jkp); 
+                  if(r_jkp<=rcut[ijkp]) {
+                    ps=r_jkp*rdr[ijkp]+1.0;
+                    ks=(int)ps;
+                    if(nr-1<ks)
+                      ks=nr-1;
+                    ps=ps-ks;
+                    if(ps>1.0)
+                      ps=1.0;
+                    betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+                        +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+                    dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+                        +pBetaS4[ijkp][ks-1];
+                    betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+                        +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+                    dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+                        +pBetaP4[ijkp][ks-1];
+                    cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+                        -dis_ij[2]*dis_jk[2])/(r_ij*r_jk); 
+                    dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+                        *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+                        *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+                        *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+                        *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+                        *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                    dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+                        *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                    gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                    gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                    gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                    amean=cosAng_ijk;
+                    gfactor2=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                    gprime2=gmean1+2.0*gmean2*amean;
+                    gmean0=sigma_g0[itype-1][ktype-1][jtype-1];
+                    gmean1=sigma_g1[itype-1][ktype-1][jtype-1];
+                    gmean2=sigma_g2[itype-1][ktype-1][jtype-1];
+                    cosAng_ikj=(dis_ik[0]*dis_jk[0]+dis_ik[1]*dis_jk[1]
+                        +dis_ik[2]*dis_jk[2])/(r_ik*r_jk); 
+                    dcA_ikj[0][0]=(-dis_jk[0]*r_ik*r_jk-cosAng_ikj
+                        *-dis_ik[0]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[1][0]=(-dis_jk[1]*r_ik*r_jk-cosAng_ikj
+                        *-dis_ik[1]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[2][0]=(-dis_jk[2]*r_ik*r_jk-cosAng_ikj
+                        *-dis_ik[2]*r_jk*r_jk)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[0][1]=(-dis_ik[0]*r_ik*r_jk-cosAng_ikj
+                        *-dis_jk[0]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[1][1]=(-dis_ik[1]*r_ik*r_jk-cosAng_ikj
+                        *-dis_jk[1]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+                    dcA_ikj[2][1]=(-dis_ik[2]*r_ik*r_jk-cosAng_ikj
+                        *-dis_jk[2]*r_ik*r_ik)/(r_ik*r_ik*r_jk*r_jk);
+                    amean=cosAng_ikj;
+                    gfactor3=gmean0+gmean1*amean
+                        +gmean2*amean*amean;
+                    gprime3=gmean1+2.0*gmean2*amean;
+                    gfactor=gfactor1*gfactor2*gfactor3;
+                    rfactor=betaS_ik*betaS_jkp;
+ 
+//EE1 is (b) Eq. 12
+ 
+                    EE1=EE1+gfactor*rfactor;
+ 
+//rcm1 is derivative of EE1 w.r.t Beta(r_ik)
+//rcm2 is derivative of EE1 w.r.t Beta(r_jk')
+//gcm1 is derivative of EE1 w.r.t cos(theta_jik)
+//gcm2 is derivative of EE1 w.r.t cos(theta_ijk)
+//gcm3 is derivative of EE1 w.r.t cos(theta_ikj)
+ 
+                    rcm1=gfactor*betaS_jkp*dBetaS_ik/r_ik;
+                    rcm2=gfactor*betaS_ik*dBetaS_jkp/r_jkp;
+                    gcm1=rfactor*gprime1*gfactor2*gfactor3;
+                    gcm2=rfactor*gfactor1*gprime2*gfactor3;
+                    gcm3=rfactor*gfactor1*gfactor2*gprime3;
+                    bt_sg[nb_ij].dEE1[0]+=
+                        gcm1*dcA_jik[0][0]
+                        -gcm2*dcA_ijk[0][0];
+                    bt_sg[nb_ij].dEE1[1]+=
+                        gcm1*dcA_jik[1][0]
+                        -gcm2*dcA_ijk[1][0];
+                    bt_sg[nb_ij].dEE1[2]+=
+                        gcm1*dcA_jik[2][0]
+                        -gcm2*dcA_ijk[2][0];
+                    bt_sg[nb_ik].dEE1[0]+=
+                        gcm1*dcA_jik[0][1]
+                        +rcm1*dis_ik[0]
+                        -gcm3*dcA_ikj[0][0];
+                    bt_sg[nb_ik].dEE1[1]+=
+                        gcm1*dcA_jik[1][1]
+                        +rcm1*dis_ik[1]
+                        -gcm3*dcA_ikj[1][0];
+                    bt_sg[nb_ik].dEE1[2]+=
+                        gcm1*dcA_jik[2][1]
+                        +rcm1*dis_ik[2]
+                        -gcm3*dcA_ikj[2][0];
+                    bt_sg[nb_jk].dEE1[0]+=
+                        gcm2*dcA_ijk[0][1]
+                        +rcm2*dis_jkp[0]
+                        -gcm3*dcA_ikj[0][1];
+                    bt_sg[nb_jk].dEE1[1]+=
+                        gcm2*dcA_ijk[1][1]
+                        +rcm2*dis_jkp[1]
+                        -gcm3*dcA_ikj[1][1];
+                    bt_sg[nb_jk].dEE1[2]+=
+                        gcm2*dcA_ijk[2][1]
+                        +rcm2*dis_jkp[2]
+                        -gcm3*dcA_ikj[2][1];
+                  }
+                }
+ 
+// k and k' and j are all different neighbors of i
+ 
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=jtmp) {
+                    kp=iilist[ltmp];;
+                    kptype = map[type[kp]]+1;
+                    if(itype==kptype)
+                      iikp=itype-1;
+                    else if(itype<kptype)
+                      iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+                    else
+                      iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+                    if((nSigBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                      ncmp=itypeSigBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    dis_ikp[0]=x[kp][0]-x[i][0]; 
+                    dis_ikp[1]=x[kp][1]-x[i][1]; 
+                    dis_ikp[2]=x[kp][2]-x[i][2]; 
+                    rsq_ikp=dis_ikp[0]*dis_ikp[0]
+                        +dis_ikp[1]*dis_ikp[1]
+                        +dis_ikp[2]*dis_ikp[2];
+                    r_ikp=sqrt(rsq_ikp); 
+                    if(r_ikp<=rcut[iikp]) {
+                      ps=r_ikp*rdr[iikp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+                          +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+                      dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+                          +pBetaS4[iikp][ks-1];
+                      betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+                          +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+                      dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+                          +pBetaP4[iikp][ks-1];
+                      gmean0=sigma_g0[jtype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][itype-1][kptype-1];
+                      cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+                          +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp); 
+                      cosAng_kikp=(dis_ik[0]*dis_ikp[0]+dis_ik[1]*dis_ikp[1]
+                          +dis_ik[2]*dis_ikp[2])/(r_ik*r_ikp); 
+                      amean=cosAng_jikp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][itype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][itype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][itype-1][kptype-1];
+                      amean=cosAng_kikp;
+                      gfactor3=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS_ik*betaS_ikp;
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//2nd CC is second term of Eq. 11 (c) for i atom where j , k & k' =neighbor of i
+ 
+                      CC=CC+2.0*gfactor*rfactor;
+                    }
+                  }
+                }
+ 
+// j and k are different neighbors of i and k' is a neighbor k not equal to i
+ 
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  kp=klist[ltmp];;
+                  kptype = map[type[kp]]+1;
+                  same_ikp=0;
+                  same_jkp=0;
+                  if(x[i][0]==x[kp][0]) {
+                    if(x[i][1]==x[kp][1]) {
+                      if(x[i][2]==x[kp][2]) {
+                        same_ikp=1;
+                      }
+                    }
+                  }
+                  if(x[j][0]==x[kp][0]) {
+                    if(x[j][1]==x[kp][1]) {
+                      if(x[j][2]==x[kp][2]) {
+                        same_jkp=1;
+                      }
+                    }
+                  }
+                  if(!same_ikp&&!same_jkp) {
+                    if(ktype==kptype)
+                      ikkp=ktype-1;
+                    else if(ktype<kptype)
+                      ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+                    else
+                      ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+                    dis_kkp[0]=x[kp][0]-x[k][0]; 
+                    dis_kkp[1]=x[kp][1]-x[k][1]; 
+                    dis_kkp[2]=x[kp][2]-x[k][2]; 
+                    rsq_kkp=dis_kkp[0]*dis_kkp[0]
+                        +dis_kkp[1]*dis_kkp[1]
+                        +dis_kkp[2]*dis_kkp[2];
+                    r_kkp=sqrt(rsq_kkp); 
+                    if(r_kkp<=rcut[ikkp]) {
+                      ps=r_kkp*rdr[ikkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+                          +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+                      dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+                          +pBetaS4[ikkp][ks-1];
+                      betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+                          +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+                      dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+                          +pBetaP4[ikkp][ks-1];
+                      sig_flag=0;
+                      if((nSigBk[n]>neigh_ct)) {
+                        printf("BOP 14:7 itypeSigBk error exit \n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                        ncmp=itypeSigBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              sig_flag=1;
+                              nkp=nsearch;
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(sig_flag==0) {
+                        nSigBk[n]=nSigBk[n]+1;
+                        nkp=nSigBk[n]-1;
+                        if((nkp>=neigh_ct)) {
+                          printf("BOP 14:7 itypeSigBk error exit \n");
+                          exit(1);
+                        }
+                        itypeSigBk[n][nkp]=kp;
+                      }
+                      cosAng_ikkp=(-dis_ik[0]*dis_kkp[0]-dis_ik[1]*dis_kkp[1]
+                          -dis_ik[2]*dis_kkp[2])/(r_ik*r_kkp); 
+                      gmean0=sigma_g0[itype-1][ktype-1][kptype-1];          
+                      gmean1=sigma_g1[itype-1][ktype-1][kptype-1];          
+                      gmean2=sigma_g2[itype-1][ktype-1][kptype-1];          
+                      amean=cosAng_ikkp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS_ik*betaS_kkp;
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//3rd CC is third term of Eq. 11 (c) for i atom 
+//where j , k =neighbor of i & k' =neighbor of k
+ 
+                      CC=CC+gfactor*rfactor;
+                    }
+                  }
+                }
+              }
+            }
+          }
+        
+//j is a neighbor of i and k is a neighbor of j not equal to i
+ 
+          for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+            if(ktmp!=ji) {
+              temp_jk=BOP_index[j]+ktmp;
+              k=jlist[ktmp];
+              klist=firstneigh[k];
+              ktype=map[type[k]]+1;
+              for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                if(x[klist[kNeij]][0]==x[j][0]) {
+                  if(x[klist[kNeij]][1]==x[j][1]) {
+                    if(x[klist[kNeij]][2]==x[j][2]) {
+                      break;
+                    }
+                  }
+                }
+              }
+              if(jtype==ktype)
+                ijk=jtype-1;
+              else if(jtype<ktype)
+                ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+              else
+                ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+              sig_flag=0;
+              if((nSigBk[n]>neigh_ct)) {
+                printf("BOP 14:7 itypeSigBk error exit \n");
+                exit(1);
+              }
+              for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                ncmp=itypeSigBk[n][nsearch];
+                if(x[ncmp][0]==x[k][0]) {
+                  if(x[ncmp][1]==x[k][1]) {
+                    if(x[ncmp][2]==x[k][2]) {
+                      new1=nsearch;
+                      sig_flag=1;
+                      break;
+                    }
+                  }
+                }
+              }
+              if(sig_flag==0) {
+                nSigBk[n]=nSigBk[n]+1;
+                new1=nSigBk[n]-1;
+                if((new1>neigh_ct)) {
+                  printf("BOP 14:7 itypeSigBk error exit \n");
+                  exit(1);
+                }
+                itypeSigBk[n][new1]=k;
+              }
+              dis_jk[0]=x[k][0]-x[j][0]; 
+              dis_jk[1]=x[k][1]-x[j][1]; 
+              dis_jk[2]=x[k][2]-x[j][2]; 
+              rsq_jk=dis_jk[0]*dis_jk[0]
+                  +dis_jk[1]*dis_jk[1]
+                  +dis_jk[2]*dis_jk[2];
+              r_jk=sqrt(rsq_jk); 
+              if(r_jk<=rcut[ijk]) {
+                ps=r_jk*rdr[ijk]+1.0;
+                ks=(int)ps;
+                if(nr-1<ks)
+                  ks=nr-1;
+                ps=ps-ks;
+                if(ps>1.0)
+                  ps=1.0;
+                betaS_jk=((pBetaS3[ijk][ks-1]*ps+pBetaS2[ijk][ks-1])*ps
+                    +pBetaS1[ijk][ks-1])*ps+pBetaS[ijk][ks-1];
+                dBetaS_jk=(pBetaS6[ijk][ks-1]*ps+pBetaS5[ijk][ks-1])*ps
+                    +pBetaS4[ijk][ks-1];
+                betaP_jk=((pBetaP3[ijk][ks-1]*ps+pBetaP2[ijk][ks-1])*ps
+                    +pBetaP1[ijk][ks-1])*ps+pBetaP[ijk][ks-1];
+                dBetaP_jk=(pBetaP6[ijk][ks-1]*ps+pBetaP5[ijk][ks-1])*ps
+                    +pBetaP4[ijk][ks-1];
+                cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+                    -dis_ij[2]*dis_jk[2])/(r_ij*r_jk); 
+                dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_sg) {
+                  new_n_tot=nb_sg+maxneigh;
+                  grow_sigma(nb_sg,new_n_tot);
+                  nb_sg=new_n_tot;
+                }
+                bt_sg[nb_jk].temp=temp_jk;
+                bt_sg[nb_jk].i=j;
+                bt_sg[nb_jk].j=k;
+                gmean0=sigma_g0[itype-1][jtype-1][ktype-1];
+                gmean1=sigma_g1[itype-1][jtype-1][ktype-1];
+                gmean2=sigma_g2[itype-1][jtype-1][ktype-1];
+                amean=cosAng_ijk;
+                gfactor1=gmean0+gmean1*amean
+                    +gmean2*amean*amean;
+                gprime1=gmean1+2.0*gmean2*amean;
+                gfactorsq=gfactor1*gfactor1;
+                gsqprime=2.0*gfactor1*gprime1;
+                rfactor1rt=betaS_jk*betaS_jk;
+                rfactor1=rfactor1rt*rfactor1rt;
+ 
+//BB is Eq. 34 (a) or Eq. 10 (c) for the j atom
+//1st DD is Eq. 11 (c) for j atom where i & k=neighbor of j
+ 
+                BB=BB+gfactorsq*rfactor1rt;
+                DD=DD+gfactorsq*rfactor1;
+ 
+//agpdpr1 is derivative of BB  w.r.t. Beta(r_jk)
+//app1 is derivative of BB w.r.t. cos(theta_ijk)
+ 
+                agpdpr1=2.0*gfactorsq*betaS_jk*dBetaS_jk/r_jk;
+                app1=rfactor1rt*gsqprime;
+                bt_sg[nb_ij].dBB[0]-=
+                    app1*dcA_ijk[0][0];
+                bt_sg[nb_ij].dBB[1]-=
+                    app1*dcA_ijk[1][0];
+                bt_sg[nb_ij].dBB[2]-=
+                    app1*dcA_ijk[2][0];
+                bt_sg[nb_jk].dBB[0]+=
+                    app1*dcA_ijk[0][1]
+                    +agpdpr1*dis_jk[0];
+                bt_sg[nb_jk].dBB[1]+=
+                    app1*dcA_ijk[1][1]
+                    +agpdpr1*dis_jk[1];
+                bt_sg[nb_jk].dBB[2]+=
+                    app1*dcA_ijk[2][1]
+                    +agpdpr1*dis_jk[2];
+ 
+//j is a neighbor of i, k and k' prime different neighbors of j not equal to i
+ 
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=ji) {
+                    temp_jkp=BOP_index[j]+ltmp;
+                    kp=jlist[ltmp];
+                    kptype=map[type[kp]]+1;
+                    if(jtype==kptype)
+                      ijkp=jtype-1;
+                    else if(jtype<kptype)
+                      ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+                    else
+                      ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+                    if((nSigBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                      ncmp=itypeSigBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            new2=nsearch;
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    dis_jkp[0]=x[kp][0]-x[j][0]; 
+                    dis_jkp[1]=x[kp][1]-x[j][1]; 
+                    dis_jkp[2]=x[kp][2]-x[j][2]; 
+                    rsq_jkp=dis_jkp[0]*dis_jkp[0]
+                        +dis_jkp[1]*dis_jkp[1]
+                        +dis_jkp[2]*dis_jkp[2];
+                    r_jkp=sqrt(rsq_jkp); 
+                    if(r_jkp<=rcut[ijkp]) {
+                      ps=r_jkp*rdr[ijkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+                        +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+                      dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+                        +pBetaS4[ijkp][ks-1];
+                      betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+                        +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+                      dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+                        +pBetaP4[ijkp][ks-1];
+                      cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+                        -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp); 
+                      dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+                        *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+                        *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+                        *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+                        *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+                        *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+                        *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      cosAng_kjkp=(dis_jk[0]*dis_jkp[0]+dis_jk[1]*dis_jkp[1]
+                        +dis_jk[2]*dis_jkp[2])/(r_jk*r_jkp); 
+                      dcA_kjkp[0][0]=(dis_jkp[0]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jk[0]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[1][0]=(dis_jkp[1]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jk[1]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[2][0]=(dis_jkp[2]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jk[2]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[0][1]=(dis_jk[0]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[1][1]=(dis_jk[1]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[2][1]=(dis_jk[2]*r_jk*r_jkp-cosAng_kjkp
+                        *dis_jkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      nb_jkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_jkp].temp=temp_jkp;
+                      bt_sg[nb_jkp].i=j;
+                      bt_sg[nb_jkp].j=kp;
+                      gmean0=sigma_g0[itype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[itype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[itype-1][jtype-1][kptype-1];
+                      amean=cosAng_ijkp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gmean0=sigma_g0[ktype-1][jtype-1][kptype-1];
+                      gmean1=sigma_g1[ktype-1][jtype-1][kptype-1];
+                      gmean2=sigma_g2[ktype-1][jtype-1][kptype-1];
+                      amean=cosAng_kjkp;
+                      gfactor3=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime3=gmean1+2.0*gmean2*amean;
+                      gfactor=gfactor1*gfactor2*gfactor3;
+                      rfactorrt=betaS_jk*betaS_jkp;
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//2nd DD is Eq. 11 (c) for j atom where i , k & k'=neighbor of j
+ 
+                      DD=DD+2.0*gfactor*rfactor;
+                    }
+                  }
+                }
+ 
+//j is a neighbor of i, k is a neighbor of j not equal to i and k' 
+//is a neighbor of k not equal to j or i
+ 
+                for(ltmp=0;ltmp<numneigh[k];ltmp++) {
+                  temp_kkp=BOP_index[k]+ltmp;
+                  kp=klist[ltmp];
+                  kptype=map[type[kp]]+1;
+                  same_ikp=0;
+                  same_jkp=0;
+                  if(x[i][0]==x[kp][0]) {
+                    if(x[i][1]==x[kp][1]) {
+                      if(x[i][2]==x[kp][2]) {
+                        same_ikp=1;
+                      }
+                    }
+                  }
+                  if(x[j][0]==x[kp][0]) {
+                    if(x[j][1]==x[kp][1]) {
+                      if(x[j][2]==x[kp][2]) {
+                        same_jkp=1;
+                      }
+                    }
+                  }
+                  if(!same_ikp&&!same_jkp) {
+                    if(ktype==kptype)
+                      ikkp=ktype-1;
+                    else if(ktype<kptype)
+                      ikkp=ktype*bop_types-ktype*(ktype+1)/2+kptype-1;
+                    else
+                      ikkp=kptype*bop_types-kptype*(kptype+1)/2+ktype-1;
+                    for(kNeij=0;kNeij<numneigh[k];kNeij++) {
+                      if(x[klist[kNeij]][0]==x[j][0]) {
+                        if(x[klist[kNeij]][1]==x[j][1]) {
+                          if(x[klist[kNeij]][2]==x[j][2]) {
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    sig_flag=0;
+                    if((nSigBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nSigBk[n];nsearch++) {
+                      ncmp=itypeSigBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            new2=nsearch;
+                            sig_flag=1;
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    if(sig_flag==0) {
+                      nSigBk[n]=nSigBk[n]+1;
+                      new2=nSigBk[n]-1;
+                      if((new2>=neigh_ct)) {
+                        printf("BOP 14:7 itypeSigBk error exit \n");
+                        exit(1);
+                      }
+                      itypeSigBk[n][new2]=kp;
+                    }
+                    dis_kkp[0]=x[kp][0]-x[k][0]; 
+                    dis_kkp[1]=x[kp][1]-x[k][1]; 
+                    dis_kkp[2]=x[kp][2]-x[k][2]; 
+                    rsq_kkp=dis_kkp[0]*dis_kkp[0]
+                        +dis_kkp[1]*dis_kkp[1]
+                        +dis_kkp[2]*dis_kkp[2];
+                    r_kkp=sqrt(rsq_kkp); 
+                    if(r_kkp<=rcut[ikkp]) {
+                      ps=r_kkp*rdr[ikkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_kkp=((pBetaS3[ikkp][ks-1]*ps+pBetaS2[ikkp][ks-1])*ps
+                          +pBetaS1[ikkp][ks-1])*ps+pBetaS[ikkp][ks-1];
+                      dBetaS_kkp=(pBetaS6[ikkp][ks-1]*ps+pBetaS5[ikkp][ks-1])*ps
+                          +pBetaS4[ikkp][ks-1];
+                      betaP_kkp=((pBetaP3[ikkp][ks-1]*ps+pBetaP2[ikkp][ks-1])*ps
+                          +pBetaP1[ikkp][ks-1])*ps+pBetaP[ikkp][ks-1];
+                      dBetaP_kkp=(pBetaP6[ikkp][ks-1]*ps+pBetaP5[ikkp][ks-1])*ps
+                          +pBetaP4[ikkp][ks-1];
+                      cosAng_jkkp=(-dis_jk[0]*dis_kkp[0]-dis_jk[1]*dis_kkp[1]
+                          -dis_jk[2]*dis_kkp[2])/(r_jk*r_kkp); 
+                      dcA_jkkp[0][0]=(dis_kkp[0]*r_jk*r_kkp-cosAng_jkkp
+                          *-dis_jk[0]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[1][0]=(dis_kkp[1]*r_jk*r_kkp-cosAng_jkkp
+                          *-dis_jk[1]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[2][0]=(dis_kkp[2]*r_jk*r_kkp-cosAng_jkkp
+                          *-dis_jk[2]*r_kkp*r_kkp)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[0][1]=(-dis_jk[0]*r_jk*r_kkp-cosAng_jkkp
+                          *dis_kkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[1][1]=(-dis_jk[1]*r_jk*r_kkp-cosAng_jkkp
+                          *dis_kkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+                      dcA_jkkp[2][1]=(-dis_jk[2]*r_jk*r_kkp-cosAng_jkkp
+                          *dis_kkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_kkp*r_kkp);
+                      nb_kkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_sg) {
+                        new_n_tot=nb_sg+maxneigh;
+                        grow_sigma(nb_sg,new_n_tot);
+                        nb_sg=new_n_tot;
+                      }
+                      bt_sg[nb_kkp].temp=temp_kkp;
+                      bt_sg[nb_kkp].i=k;
+                      bt_sg[nb_kkp].j=kp;
+                      gmean0=sigma_g0[jtype-1][ktype-1][kptype-1];
+                      gmean1=sigma_g1[jtype-1][ktype-1][kptype-1];
+                      gmean2=sigma_g2[jtype-1][ktype-1][kptype-1];
+                      amean=cosAng_jkkp;
+                      gfactor2=gmean0+gmean1*amean
+                          +gmean2*amean*amean;
+                      gprime2=gmean1+2.0*gmean2*amean;
+                      gfactorsq2=gfactor2*gfactor2;
+                      gsqprime2=2.0*gfactor2*gprime2;
+                      gfactor=gfactorsq*gfactorsq2;
+                      rfactorrt=betaS_jk*betaS_kkp;
+                      rfactor=rfactorrt*rfactorrt;
+ 
+//3rd DD is Eq. 11 (c) for j atom where i & k=neighbor of j & k'=neighbor of k
+ 
+                      DD=DD+gfactor*rfactor;
+                    }
+                  }
+                }
+              }
+            }
+          }
+ 
+          sig_flag=0;
+          if(FF<=0.000001) {
+            sigB[n]=0.0;
+            sig_flag=1;
+          }
+          if(sig_flag==0) {
+            if(AA<0.0)
+              AA=0.0;
+            if(BB<0.0)
+              BB=0.0;
+            if(CC<0.0)
+              CC=0.0;
+            if(DD<0.0)
+              DD=0.0;
+ 
+// AA and BB are the representations of (a) Eq. 34 and (b) Eq. 9
+// for atoms i and j respectively
+ 
+            AAC=AA+BB;
+            BBC=AA*BB;
+            CCC=AA*AA+BB*BB;
+            DDC=CC+DD;
+ 
+//EEC is a modified form of (a) Eq. 33
+ 
+            EEC=(DDC-CCC)/(AAC+2.0*small1);
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                bt_sg[m].dAAC[0]=bt_sg[m].dAA[0]
+                    +bt_sg[m].dBB[0];
+                bt_sg[m].dAAC[1]=bt_sg[m].dAA[1]
+                    +bt_sg[m].dBB[1];
+                bt_sg[m].dAAC[2]=bt_sg[m].dAA[2]
+                    +bt_sg[m].dBB[2];
+              } 
+            }
+            UT=EEC*FF+BBC+small3[iij];
+            UT=1.0/sqrt(UT);
+ 
+// FFC is slightly modified form of (a) Eq. 31
+// GGC is slightly modified form of (a) Eq. 32
+// bndtmp is a slightly modified form of (a) Eq. 30 and (b) Eq. 8
+ 
+            FFC=BBC*UT;
+            GGC=EEC*UT;
+            bndtmp=(FF+sigma_delta[iij]*sigma_delta[iij])
+                +sigma_c[iij]*AAC+small4;
+            UTcom=-0.5*UT*UT*UT;
+            psign=1.0;
+            bndtmp0=1.0/sqrt(bndtmp);
+            sigB1[n]=psign*betaS_ij*bndtmp0;
+            bndtmp=-0.5*bndtmp0*bndtmp0*bndtmp0;
+            bndtmp1=psign*bndtmp0+psign*betaS_ij
+                *bndtmp*2.0*betaS_ij;
+            bndtmp1=bndtmp1*dBetaS_ij/r_ij;
+            bndtmp2=psign*betaS_ij*bndtmp*sigma_c[iij];
+            setting=0;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                if(temp_kk==temp_ij&&setting==0) {
+                  bt_sg[m].dSigB1[0]=bndtmp1*dis_ij[0]
+                      +(bndtmp2*bt_sg[m].dAAC[0]);
+                  bt_sg[m].dSigB1[1]=bndtmp1*dis_ij[1]
+                      +(bndtmp2*bt_sg[m].dAAC[1]);
+                  bt_sg[m].dSigB1[2]=bndtmp1*dis_ij[2]
+                      +(bndtmp2*bt_sg[m].dAAC[2]);
+                  setting=1;
+                }
+                else if(temp_kk==temp_ji&&setting==0) {
+                  bt_sg[m].dSigB1[0]=-bndtmp1*dis_ij[0]
+                      +(bndtmp2*bt_sg[m].dAAC[0]);
+                  bt_sg[m].dSigB1[1]=-bndtmp1*dis_ij[1]
+                      +(bndtmp2*bt_sg[m].dAAC[1]);
+                  bt_sg[m].dSigB1[2]=-bndtmp1*dis_ij[2]
+                      +(bndtmp2*bt_sg[m].dAAC[2]);
+                  setting=1;
+                }
+                else {
+                  bt_sg[m].dSigB1[0]=(bndtmp2*bt_sg[m].dAAC[0]);
+                  bt_sg[m].dSigB1[1]=(bndtmp2*bt_sg[m].dAAC[1]);
+                  bt_sg[m].dSigB1[2]=(bndtmp2*bt_sg[m].dAAC[2]);
+                }
+              }
+            }
+ 
+//This loop is to ensure there is not an error for atoms with no neighbors (deposition)
+ 
+            if(nb_t==0) {
+              if(j>i) {
+                bt_sg[0].dSigB1[0]=bndtmp1*dis_ij[0];
+                bt_sg[0].dSigB1[1]=bndtmp1*dis_ij[1];
+                bt_sg[0].dSigB1[2]=bndtmp1*dis_ij[2];
+              }
+              else {
+                bt_sg[0].dSigB1[0]=-bndtmp1*dis_ij[0];
+                bt_sg[0].dSigB1[1]=-bndtmp1*dis_ij[1];
+                bt_sg[0].dSigB1[2]=-bndtmp1*dis_ij[2];
+              }
+              for(pp=0;pp<3;pp++) {
+                bt_sg[0].dAA[pp]=0.0;
+                bt_sg[0].dBB[pp]=0.0;
+                bt_sg[0].dEE1[pp]=0.0;
+                bt_sg[0].dFF[pp]=0.0;
+                bt_sg[0].dAAC[pp]=0.0;
+                bt_sg[0].dSigB[pp]=0.0;
+              }
+              bt_sg[0].i=i;
+              bt_sg[0].j=j;
+              bt_sg[0].temp=temp_ij;
+              nb_t++;
+              if(nb_t>nb_sg) {
+                new_n_tot=nb_sg+maxneigh;
+                grow_sigma(nb_sg,new_n_tot);
+                nb_sg=new_n_tot;
+              }
+            }
+            ps=sigB1[n]*rdBO+1.0;
+            ks=(int)ps;
+            if(nBOt-1<ks)
+              ks=nBOt-1;
+            ps=ps-ks;
+            if(ps>1.0)
+              ps=1.0;
+            dsigB1=((FsigBO3[iij][ks-1]*ps+FsigBO2[iij][ks-1])*ps
+                +FsigBO1[iij][ks-1])*ps+FsigBO[iij][ks-1];
+            dsigB2=(FsigBO6[iij][ks-1]*ps+FsigBO5[iij][ks-1])*ps+FsigBO4[iij][ks-1];
+            part0=(FF+0.5*AAC+small5);
+            part1=(sigma_f[iij]-0.5)*sigma_k[iij];
+            part2=1.0-part1*EE1/part0;
+            part3=dsigB1*part1/part0;
+            part4=part3/part0*EE1;
+ 
+// sigB is the final expression for (a) Eq. 6 and (b) Eq. 11
+ 
+            sigB[n]=dsigB1*part2;
+            pp1=2.0*betaS_ij;
+            for(m=0;m<nb_t;m++) {
+              if((bt_sg[m].i>-1)&&(bt_sg[m].j>-1)) {
+                temp_kk=bt_sg[m].temp;
+                bt_ij=bt_sg[m].temp;
+                bt_i=bt_sg[m].i;
+                bt_j=bt_sg[m].j;
+                xtmp[0]=x[bt_j][0]-x[bt_i][0];
+                xtmp[1]=x[bt_j][1]-x[bt_i][1];
+                xtmp[2]=x[bt_j][2]-x[bt_i][2];
+                for(pp=0;pp<3;pp++) {
+                  bt_sg[m].dSigB[pp]=dsigB2*part2*bt_sg[m].dSigB1[pp]
+                      -part3*bt_sg[m].dEE1[pp]
+                      +part4*(bt_sg[m].dFF[pp]
+                      +0.5*bt_sg[m].dAAC[pp]);
+                }
+                for(pp=0;pp<3;pp++) {
+                  ftmp[pp]=pp1*bt_sg[m].dSigB[pp];
+                  f[bt_i][pp]-=ftmp[pp];
+                  f[bt_j][pp]+=ftmp[pp];
+                }
+                if(evflag) {
+                  ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                      ,ftmp[2],xtmp[0],xtmp[1],xtmp[2]);
+                }
+              }
+            }
+          }
+          n++;
+        }
+      }
+    }
+  }
+  destroy_sigma();
+}
+
+void PairBOP::PiBo()
+{
+  int new_n_tot;
+  int i,j,k,kp,m,n,pp,nb_t;
+  int iij,ji,ki;
+  int nsearch,ncmp;
+  int i_tag,j_tag;
+  int njik,ngj,ngk,nglj,ngl,ngi;
+  int nkjkp,nijkp,ngli,nkikp,njikp;
+  int itmp,ltmp,jtmp,ktmp;
+  int nlocal,pi_flag;
+  int inum,*ilist,*iilist,*jlist;
+  int **firstneigh,*numneigh; 
+  int itype,jtype;
+  int temp_ij,temp_ik,temp_ikp;
+  int temp_ji,temp_jki,temp_jk,temp_jkp;
+  int ang_jikp,ang_kikp,ang_ijk;
+  int ang_ijkp,ang_kjkp,ang_jik;
+  int nb_ij,nb_ik,nb_jk,nb_ikp,nb_jkp;
+  int bt_ij,bt_i,bt_j;
+  double AA,BB,CC,DD,EE,FF;
+  double cosSq,sinFactor,cosFactor;
+  double cosSq1,dotV,BBrt,AB1,AB2;
+  double BBrtR,ABrtR,ABrtR1,ABrtR2;
+  double angFactor,angFactor1,angFactor2;
+  double angFactor3,angFactor4,angRfactor;
+  double dAngR1,dAngR2,agpdpr3;
+  double agpdpr1,agpdpr2,app1,app2,app3;
+  double betaCapSq1,dbetaCapSq1;
+  double betaCapSq2,dbetaCapSq2;
+  double betaCapSum,ftmp[3];
+  double dPiB1,dPiB2,dPiB3,pp2;
+  double **f = atom->f;
+  double **x = atom->x;
+  int *type = atom->type;
+  int *tag = atom->tag;
+  int newton_pair = force->newton_pair;
+
+  nlocal = atom->nlocal;
+  inum = list->inum;
+  ilist = list->ilist;
+  numneigh = list->numneigh;
+  firstneigh = list->firstneigh;
+  
+  n=0;
+
+// Loop over all local atoms for i
+
+  if(nb_pi>16) {
+    nb_pi=16;
+  }
+  if(nb_pi==0) {
+    nb_pi=(maxneigh)*(maxneigh/2);
+  }
+  if(allocate_pi) {
+    destroy_pi();
+  }
+  create_pi(nb_pi);   
+  for(itmp=0;itmp<inum;itmp++) {
+    nb_t=0;
+    i = ilist[itmp];
+    itype = map[type[i]]+1;
+    i_tag=tag[i];
+
+// j is a loop over all neighbors of i
+
+    iilist=firstneigh[i];
+    for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+      temp_ij=BOP_index[i]+jtmp;
+      if(temp_ij>=neigh_total) {
+        printf("neigh_total too big %7d\n",temp_ij);
+        exit(1);
+      }
+      if(neigh_flag[temp_ij]) {
+        for(m=0;m<nb_pi;m++) {
+          for(pp=0;pp<3;pp++) { 
+            bt_pi[m].dAA[pp]=0.0; 
+            bt_pi[m].dBB[pp]=0.0; 
+            bt_pi[m].dPiB[pp]=0.0; 
+          }
+          bt_pi[m].i=-1;
+          bt_pi[m].j=-1;
+        }
+        j=iilist[jtmp];
+        jlist=firstneigh[j];
+        jtype=map[type[j]]+1;
+        j_tag=tag[j];
+        nb_t=0;
+        ftmp[0]=0.0;
+        ftmp[1]=0.0;
+        ftmp[2]=0.0;
+        nb_ij=nb_t;
+        nb_t++;
+        if(nb_t>nb_pi) { 
+          new_n_tot=nb_pi+maxneigh;
+          grow_pi(nb_pi,new_n_tot);
+          nb_pi=new_n_tot;
+        }
+        bt_pi[nb_ij].i=i;
+        bt_pi[nb_ij].j=j;
+        bt_pi[nb_ij].temp=temp_ij;
+        if(j_tag>=i_tag) {
+          if(n>=neigh_total) {
+            printf("BOP 16:n is too large \n");
+            exit(1);
+          }
+          if(itype==jtype)
+            iij=itype-1;
+          else if(itype<jtype)
+            iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+          else
+            iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+          AA=0.0;
+          BB=0.0;
+          nPiBk[n]=0;
+          for(ji=0;ji<numneigh[j];ji++) {
+            temp_ji=BOP_index[j]+ji;
+            if(temp_ji>=neigh_total) {
+              printf("neigh_total too big %7d\n",temp_ji);
+              exit(1);
+            }
+            if(x[jlist[ji]][0]==x[i][0]) {
+              if(x[jlist[ji]][1]==x[i][1]) {
+                if(x[jlist[ji]][2]==x[i][2]) {
+                  if(!neigh_flag[temp_ji]) {
+                    printf("BOP 15:error 7 flag %7d temp %7d %7d\n",neigh_flag[temp_ji],temp_ji,temp_ij);
+                    exit(1);
+                  }
+                  break;
+                }
+              }
+            }
+          }
+
+// j and k are different neighbors of i
+
+          for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+            if(ktmp!=jtmp) {
+              temp_ik=BOP_index[i]+ktmp;
+              if(temp_ik>=neigh_total) {
+                printf("neigh_total too big %7d\n",temp_ik);
+                exit(1);
+              }
+              if(neigh_flag[temp_ik]) {
+                k=iilist[ktmp];
+                if(jtmp<ktmp) {
+                  njik=jtmp*(2*numneigh[i]-jtmp-1)/2+(ktmp-jtmp)-1;
+                  ngj=0;
+                  ngk=1;
+                }
+                else {
+                  njik=ktmp*(2*numneigh[i]-ktmp-1)/2+(jtmp-ktmp)-1;
+                  ngj=1;
+                  ngk=0;
+                }
+                ang_jik=cos_index[i]+njik;
+                if(ang_jik>=cos_total) {
+                  printf("1 ang too big %7d\n",ang_jik);
+                  exit(1);
+                }
+                nb_ik=nb_t;
+                nb_t++;
+                if(nb_t>nb_pi) {
+                  new_n_tot=nb_pi+maxneigh;
+                  grow_pi(nb_pi,new_n_tot);
+                  nb_pi=new_n_tot;
+                }
+                bt_pi[nb_ik].i=i;
+                bt_pi[nb_ik].j=k;
+                bt_pi[nb_ik].temp=temp_ik;
+                cosSq=cosAng[ang_jik]*cosAng[ang_jik];
+                sinFactor=.5*(1.0-cosSq)*pi_p[itype-1]*betaS[temp_ik];
+                cosFactor=.5*(1.0+cosSq)*betaP[temp_ik];
+                betaCapSq1=pi_p[itype-1]*betaS[temp_ik]*betaS[temp_ik]-betaP[temp_ik]
+                    *betaP[temp_ik];
+                dbetaCapSq1=2.0*pi_p[itype-1]*betaS[temp_ik]*dBetaS[temp_ik]
+                    -2.0*betaP[temp_ik]*dBetaP[temp_ik];
+
+//AA is Eq. 37 (a) and Eq. 19 (b) or i atoms 
+//1st BB is first term of Eq. 38 (a) where j and k =neighbors i
+
+                AA=AA+sinFactor*betaS[temp_ik]+cosFactor*betaP[temp_ik];
+                BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+//agpdpr1 is derivative of AA w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//app1 is derivative of AA w.r.t. for atom i w.r.t. cos(theta_jik)
+//app2 is derivative of BB w.r.t. for atom i w.r.t. cos(theta_jik)
+
+                agpdpr1=(2.0*sinFactor*dBetaS[temp_ik]+2.0*cosFactor
+                    *dBetaP[temp_ik])/rij[temp_ik];
+                app1=cosAng[ang_jik]*(-pi_p[itype-1]*betaS[temp_ik]*betaS[temp_ik]
+                    +betaP[temp_ik]*betaP[temp_ik]);
+                app2=-(1.0-cosSq)*cosAng[ang_jik]*betaCapSq1*betaCapSq1;
+                agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/rij[temp_ik];
+                if((nPiBk[n]>=neigh_ct)) {
+                  printf("BOP 14:7 itypeSigBk error exit \n");
+                  exit(1);
+                }
+                itypePiBk[n][nPiBk[n]]=k;
+                bt_pi[nb_ij].dAA[0]+=
+                    app1*dcAng[ang_jik][0][ngj];
+                bt_pi[nb_ij].dAA[1]+=
+                    app1*dcAng[ang_jik][1][ngj];
+                bt_pi[nb_ij].dAA[2]+=
+                    app1*dcAng[ang_jik][2][ngj];
+                bt_pi[nb_ij].dBB[0]+=
+                    app2*dcAng[ang_jik][0][ngj];
+                bt_pi[nb_ij].dBB[1]+=
+                    app2*dcAng[ang_jik][1][ngj];
+                bt_pi[nb_ij].dBB[2]+=
+                    app2*dcAng[ang_jik][2][ngj];
+                bt_pi[nb_ik].dAA[0]+=
+                    agpdpr1*disij[0][temp_ik]
+                    +app1*dcAng[ang_jik][0][ngk];
+                bt_pi[nb_ik].dAA[1]+=
+                    agpdpr1*disij[1][temp_ik]
+                    +app1*dcAng[ang_jik][1][ngk];
+                bt_pi[nb_ik].dAA[2]+=
+                    agpdpr1*disij[2][temp_ik]
+                    +app1*dcAng[ang_jik][2][ngk];
+                bt_pi[nb_ik].dBB[0]+=
+                    app2*dcAng[ang_jik][0][ngk]
+                    +agpdpr2*disij[0][temp_ik];
+                bt_pi[nb_ik].dBB[1]+=
+                    app2*dcAng[ang_jik][1][ngk]
+                    +agpdpr2*disij[1][temp_ik];
+                bt_pi[nb_ik].dBB[2]+=
+                    app2*dcAng[ang_jik][2][ngk]
+                    +agpdpr2*disij[2][temp_ik];
+
+// j and k and k' are different neighbors of i 
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=jtmp) {
+                    temp_ikp=BOP_index[i]+ltmp;
+                    if(temp_ikp>=neigh_total) {
+                       printf("neigh_total too big %7d\n",temp_ikp);
+                       exit(1);
+                    }
+                    if(neigh_flag[temp_ikp]) {
+                      kp=iilist[ltmp];
+                      if((nPiBk[n]>neigh_ct)) {
+                        printf("BOP 14:7 itypeSigBk error exit \n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                        ncmp=itypePiBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      nkikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(ktmp-ltmp)-1;
+                      if(jtmp<ltmp) {
+                        njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+                        nglj=0;
+                        ngl=1;
+                      }
+                      else {
+                        njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+                        nglj=1;
+                        ngl=0;
+                      }
+                      ang_jikp=cos_index[i]+njikp;
+                      if(ang_jikp>=cos_total) {
+                        printf("2 ang too big %7d\n",ang_jikp);
+                        exit(1);
+                      }
+                      nb_ikp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_pi) {
+                        new_n_tot=nb_pi+maxneigh;
+                        grow_pi(nb_pi,new_n_tot);
+                        nb_pi=new_n_tot;
+                      }
+                      bt_pi[nb_ikp].i=i;
+                      bt_pi[nb_ikp].j=kp;
+                      bt_pi[nb_ikp].temp=temp_ikp;
+                      ang_kikp=cos_index[i]+nkikp;
+                      if(ang_kikp>=cos_total) {
+                        printf("3 ang too big %7d\n",ang_kikp);
+                        exit(1);
+                      }
+                      betaCapSq2=pi_p[itype-1]*betaS[temp_ikp]*betaS[temp_ikp]
+                          -betaP[temp_ikp]*betaP[temp_ikp];
+                      dbetaCapSq2=2.0*pi_p[itype-1]*betaS[temp_ikp]*dBetaS[temp_ikp]
+                          -2.0*betaP[temp_ikp]*dBetaP[temp_ikp];
+                      cosSq1=cosAng[ang_jikp]*cosAng[ang_jikp];
+                      angFactor=cosAng[ang_kikp]-cosAng[ang_jikp]*cosAng[ang_jik];
+                      angFactor1=4.0*angFactor;
+                      angFactor2=-angFactor1*cosAng[ang_jikp]
+                          +2.0*cosAng[ang_jik]*(1.0-cosSq1);
+                      angFactor3=-angFactor1*cosAng[ang_jik]
+                          +2.0*cosAng[ang_jikp]*(1.0-cosSq);
+                      angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+                      betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//2nd BB is third term of Eq. 38 (a) where j , k and k'=neighbors i
+
+                      BB=BB+betaCapSum*angFactor4;
+
+//agpdpr1 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik')
+//app1 is derivative of BB 3rd term w.r.t. cos(theta_kik')
+//app2 is derivative of BB 3rd term w.r.t. cos(theta_jik)
+//app3 is derivative of BB 3rd term w.r.t. cos(theta_jik')
+
+                      app1=betaCapSum*angFactor1;
+                      app2=betaCapSum*angFactor2;
+                      app3=betaCapSum*angFactor3;
+                      agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/rij[temp_ik];
+                      agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/rij[temp_ikp];
+
+                      bt_pi[nb_ij].dBB[0]+=
+                          app2*dcAng[ang_jik][0][ngj]
+                          +app3*dcAng[ang_jikp][0][nglj]; 
+                      bt_pi[nb_ij].dBB[1]+=
+                          app2*dcAng[ang_jik][1][ngj]
+                          +app3*dcAng[ang_jikp][1][nglj]; 
+                      bt_pi[nb_ij].dBB[2]+=
+                          app2*dcAng[ang_jik][2][ngj]
+                          +app3*dcAng[ang_jikp][2][nglj]; 
+                      bt_pi[nb_ik].dBB[0]+=
+                          agpdpr1*disij[0][temp_ik]
+                          +app1*dcAng[ang_kikp][0][1]
+                          +app2*dcAng[ang_jik][0][ngk];
+                      bt_pi[nb_ik].dBB[1]+=
+                          agpdpr1*disij[1][temp_ik]
+                          +app1*dcAng[ang_kikp][1][1]
+                          +app2*dcAng[ang_jik][1][ngk];
+                      bt_pi[nb_ik].dBB[2]+=
+                          agpdpr1*disij[2][temp_ik]
+                          +app1*dcAng[ang_kikp][2][1]
+                          +app2*dcAng[ang_jik][2][ngk];
+                      bt_pi[nb_ikp].dBB[0]+=
+                          agpdpr2*disij[0][temp_ikp]
+                          +app1*dcAng[ang_kikp][0][0]
+                          +app3*dcAng[ang_jikp][0][ngl];
+                      bt_pi[nb_ikp].dBB[1]+=
+                          agpdpr2*disij[1][temp_ikp]
+                          +app1*dcAng[ang_kikp][1][0]
+                          +app3*dcAng[ang_jikp][1][ngl];
+                      bt_pi[nb_ikp].dBB[2]+=
+                          agpdpr2*disij[2][temp_ikp]
+                          +app1*dcAng[ang_kikp][2][0]
+                          +app3*dcAng[ang_jikp][2][ngl];
+                    }
+                  }
+                }
+                nPiBk[n]=nPiBk[n]+1;
+              }
+            }
+          }
+
+//j is a neighbor of i and k is a neighbor of j and equal to i
+
+          for(ki=0;ki<numneigh[j];ki++) {
+            temp_jki=BOP_index[j]+ki;
+            if(temp_jki>=neigh_total) {
+              printf("neigh_total too big %7d\n",temp_jki);
+              exit(1);
+            }
+            k=jlist[ki];
+            if(x[k][0]==x[i][0]) {
+              if(x[k][1]==x[i][1]) {
+                if(x[k][2]==x[i][2]) {
+                  if(!neigh_flag[temp_jki]) {
+                    printf("error 8 \n");
+                  }
+                  break;
+                }
+              }
+            }
+          }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+          for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+            if(ktmp!=ki) {
+              temp_jk=BOP_index[j]+ktmp;
+              if(temp_jk>=neigh_total) {
+                printf("neigh_total too big %7d\n",temp_jk);
+                exit(1);
+              }
+              if(neigh_flag[temp_jk]) {
+                k=jlist[ktmp];
+                pi_flag=0;
+                if((nPiBk[n]>neigh_ct)) {
+                  printf("BOP 14:7 itypeSigBk error exit \n");
+                  exit(1);
+                }
+                for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                  ncmp=itypePiBk[n][nsearch];
+                  if(x[ncmp][0]==x[k][0]) {
+                    if(x[ncmp][1]==x[k][1]) {
+                      if(x[ncmp][2]==x[k][2]) {
+                        pi_flag=1;
+                        break;
+                      } 
+                    } 
+                  } 
+                } 
+                if(pi_flag==0) {
+                  if((nPiBk[n]>=neigh_ct)) {
+                    printf("BOP 14:7 itypeSigBk error exit \n");
+                    exit(1);
+                  }
+                  itypePiBk[n][nPiBk[n]]=k;
+                } 
+                if(ktmp<ki) {
+                  njik=ktmp*(2*numneigh[j]-ktmp-1)/2+(ki-ktmp)-1;
+                  ngi=1;
+                  ngk=0;
+                } 
+                else {
+                  njik=ki*(2*numneigh[j]-ki-1)/2+(ktmp-ki)-1;
+                  ngi=0;
+                  ngk=1;
+                }
+                ang_ijk=cos_index[j]+njik;
+                if(ang_ijk>=cos_total) {
+                  printf("4 ang too big %7d\n",ang_ijk);
+                  exit(1);
+                }
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_pi) {
+                  new_n_tot=nb_pi+maxneigh;
+                  grow_pi(nb_pi,new_n_tot);
+                  nb_pi=new_n_tot;
+                }
+                bt_pi[nb_jk].i=j;
+                bt_pi[nb_jk].j=k;
+                bt_pi[nb_jk].temp=temp_jk;
+                cosSq=cosAng[ang_ijk]*cosAng[ang_ijk];
+                sinFactor=.5*(1.0-cosSq)*pi_p[jtype-1]*betaS[temp_jk];
+                cosFactor=.5*(1.0+cosSq)*betaP[temp_jk];
+                betaCapSq1=pi_p[jtype-1]*betaS[temp_jk]*betaS[temp_jk]
+                    -betaP[temp_jk]*betaP[temp_jk];
+                dbetaCapSq1=2.0*pi_p[jtype-1]*betaS[temp_jk]*dBetaS[temp_jk]
+                    -2.0*betaP[temp_jk]*dBetaP[temp_jk];
+
+//AA is Eq. 37 (a) and Eq. 19 (b) for j atoms 
+//3rd BB is 2nd term of Eq. 38 (a) where i and k =neighbors j
+
+                AA=AA+sinFactor*betaS[temp_jk]+cosFactor*betaP[temp_jk];
+                BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+//agpdpr1 is derivative of AA for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB for atom j w.r.t. Beta(r_jk)
+//app1 is derivative of AA for j atom w.r.t. cos(theta_ijk)
+//app2 is derivative of BB 2nd term w.r.t. cos(theta_ijk) 
+
+                agpdpr1=(2.0*sinFactor*dBetaS[temp_jk]+2.0*cosFactor
+                    *dBetaP[temp_jk])/rij[temp_jk];
+                agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/rij[temp_jk];
+                app1=cosAng[ang_ijk]*(-pi_p[jtype-1]*betaS[temp_jk]*betaS[temp_jk]
+                    +betaP[temp_jk]*betaP[temp_jk]);
+                app2=-(1.0-cosSq)*cosAng[ang_ijk]*betaCapSq1*betaCapSq1;
+                bt_pi[nb_ij].dAA[0]-=
+                    app1*dcAng[ang_ijk][0][ngi];
+                bt_pi[nb_ij].dAA[1]-=
+                    app1*dcAng[ang_ijk][1][ngi];
+                bt_pi[nb_ij].dAA[2]-=
+                    app1*dcAng[ang_ijk][2][ngi];
+                bt_pi[nb_ij].dBB[0]-=
+                    app2*dcAng[ang_ijk][0][ngi];
+                bt_pi[nb_ij].dBB[1]-=
+                    app2*dcAng[ang_ijk][1][ngi];
+                bt_pi[nb_ij].dBB[2]-=
+                    app2*dcAng[ang_ijk][2][ngi];
+                bt_pi[nb_jk].dAA[0]+=
+                    agpdpr1*disij[0][temp_jk]
+                    +app1*dcAng[ang_ijk][0][ngk];
+                bt_pi[nb_jk].dAA[1]+=
+                    agpdpr1*disij[1][temp_jk]
+                    +app1*dcAng[ang_ijk][1][ngk];
+                bt_pi[nb_jk].dAA[2]+=
+                    agpdpr1*disij[2][temp_jk]
+                    +app1*dcAng[ang_ijk][2][ngk];
+                bt_pi[nb_jk].dBB[0]+=
+                    app2*dcAng[ang_ijk][0][ngk]
+                    +agpdpr2*disij[0][temp_jk];
+                bt_pi[nb_jk].dBB[1]+=
+                    app2*dcAng[ang_ijk][1][ngk]
+                    +agpdpr2*disij[1][temp_jk];
+                bt_pi[nb_jk].dBB[2]+=
+                    app2*dcAng[ang_ijk][2][ngk]
+                    +agpdpr2*disij[2][temp_jk];
+            
+//j is a neighbor of i and k and k' are different neighbors of j not equal to i
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=ki) {
+                    temp_jkp=BOP_index[j]+ltmp;
+                    if(temp_jkp>=neigh_total) {
+                      printf("neigh_total too big %7d\n",temp_jkp);
+                      exit(1);
+                    }
+                    if(neigh_flag[temp_jkp]) {
+                      kp=jlist[ltmp];
+                      if((nPiBk[n]>neigh_ct)) {
+                        printf("BOP 14:7 itypeSigBk error exit \n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                        ncmp=itypePiBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      nkjkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ktmp-ltmp)-1;
+                      if(ki<ltmp) {
+                        nijkp=ki*(2*numneigh[j]-ki-1)/2+(ltmp-ki)-1;
+                        ngli=0;
+                        ngl=1;
+                      }
+                      else {
+                        nijkp=ltmp*(2*numneigh[j]-ltmp-1)/2+(ki-ltmp)-1;
+                        ngli=1;
+                        ngl=0;
+                      }
+                      ang_ijkp=cos_index[j]+nijkp;
+                      if(ang_ijkp>=cos_total) {
+                        printf("5 ang too big %7d\n",ang_ijkp);
+                        exit(1);
+                      }
+                      ang_kjkp=cos_index[j]+nkjkp;
+                      if(ang_kjkp>=cos_total) {
+                        printf("6 ang too big %7d\n",ang_kjkp);
+                        exit(1);
+                      }
+                      nb_jkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_pi) {
+                        new_n_tot=nb_pi+maxneigh;
+                        grow_pi(nb_pi,new_n_tot);
+                        nb_pi=new_n_tot;
+                      }
+                      bt_pi[nb_jkp].i=j;
+                      bt_pi[nb_jkp].j=kp;
+                      bt_pi[nb_jkp].temp=temp_jkp;
+                      betaCapSq2=pi_p[jtype-1]*betaS[temp_jkp]*betaS[temp_jkp]
+                          -betaP[temp_jkp]*betaP[temp_jkp];
+                      dbetaCapSq2=2.0*pi_p[jtype-1]*betaS[temp_jkp]*dBetaS[temp_jkp]
+                          -2.0*betaP[temp_jkp]*dBetaP[temp_jkp];
+                      cosSq1=cosAng[ang_ijkp]*cosAng[ang_ijkp];
+                      angFactor=cosAng[ang_kjkp]-cosAng[ang_ijkp]*cosAng[ang_ijk];
+                      angFactor1=4.0*angFactor;
+                      angFactor2=-angFactor1*cosAng[ang_ijkp]
+                          +2.0*cosAng[ang_ijk]*(1.0-cosSq1);
+                      angFactor3=-angFactor1*cosAng[ang_ijk]
+                          +2.0*cosAng[ang_ijkp]*(1.0-cosSq);
+                      angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+                      betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//4th BB is 4th term of Eq. 38 (a) where i , k and k' =neighbors j
+
+                      BB=BB+betaCapSum*angFactor4;
+
+//app1 is derivative of BB 4th term w.r.t. cos(theta_kjk') 
+//app2 is derivative of BB 4th term w.r.t. cos(theta_ijk) 
+//app3 is derivative of BB 4th term w.r.t. cos(theta_ijk') 
+//agpdpr1 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk')
+
+                      app1=betaCapSum*angFactor1;
+                      app2=betaCapSum*angFactor2;
+                      app3=betaCapSum*angFactor3;
+                      agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/rij[temp_jk];
+                      agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/rij[temp_jkp];
+
+                      bt_pi[nb_ij].dBB[0]-=
+                          app3*dcAng[ang_ijkp][0][ngli]
+                          +app2*dcAng[ang_ijk][0][ngi]; 
+                      bt_pi[nb_ij].dBB[1]-=
+                          app3*dcAng[ang_ijkp][1][ngli]
+                          +app2*dcAng[ang_ijk][1][ngi]; 
+                      bt_pi[nb_ij].dBB[2]-=
+                          app3*dcAng[ang_ijkp][2][ngli]
+                          +app2*dcAng[ang_ijk][2][ngi]; 
+                      bt_pi[nb_jk].dBB[0]+=
+                          agpdpr1*disij[0][temp_jk]
+                          +app1*dcAng[ang_kjkp][0][1]
+                          +app2*dcAng[ang_ijk][0][ngk];
+                      bt_pi[nb_jk].dBB[1]+=
+                          agpdpr1*disij[1][temp_jk]
+                          +app1*dcAng[ang_kjkp][1][1]
+                          +app2*dcAng[ang_ijk][1][ngk];
+                      bt_pi[nb_jk].dBB[2]+=
+                          agpdpr1*disij[2][temp_jk]
+                          +app1*dcAng[ang_kjkp][2][1]
+                          +app2*dcAng[ang_ijk][2][ngk];
+                      bt_pi[nb_jkp].dBB[0]+=
+                          agpdpr2*disij[0][temp_jkp]
+                          +app1*dcAng[ang_kjkp][0][0]
+                          +app3*dcAng[ang_ijkp][0][ngl];
+                      bt_pi[nb_jkp].dBB[1]+=
+                          agpdpr2*disij[1][temp_jkp]
+                          +app1*dcAng[ang_kjkp][1][0]
+                          +app3*dcAng[ang_ijkp][1][ngl];
+                      bt_pi[nb_jkp].dBB[2]+=
+                          agpdpr2*disij[2][temp_jkp]
+                          +app1*dcAng[ang_kjkp][2][0]
+                          +app3*dcAng[ang_ijkp][2][ngl];
+                    }
+                  }
+                }
+
+//j and k' are different neighbors of i and k is a neighbor of j not equal to i
+
+                for(ltmp=0;ltmp<numneigh[i];ltmp++) {
+                  if(ltmp!=jtmp) {
+                    temp_ikp=BOP_index[i]+ltmp;
+                    if(temp_ikp>=neigh_total) {
+                      printf("neigh_total too big %7d\n",temp_ikp);
+                      exit(1);
+                    }
+                    if(neigh_flag[temp_ikp]) {
+                      kp=iilist[ltmp];
+                      if((nPiBk[n]>neigh_ct)) {
+                        printf("BOP 14:7 itypeSigBk error exit \n");
+                        exit(1);
+                      }
+                      for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                        ncmp=itypePiBk[n][nsearch];
+                        if(x[ncmp][0]==x[kp][0]) {
+                          if(x[ncmp][1]==x[kp][1]) {
+                            if(x[ncmp][2]==x[kp][2]) {
+                              break;
+                            }
+                          }
+                        }
+                      }
+                      if(ltmp<jtmp) {
+                        njikp=ltmp*(2*numneigh[i]-ltmp-1)/2+(jtmp-ltmp)-1;
+                        ngl=1;
+                        nglj=0;
+                      }
+                      else {
+                        njikp=jtmp*(2*numneigh[i]-jtmp-1)/2+(ltmp-jtmp)-1;
+                        ngl=0;
+                        nglj=1;
+                      }
+                      ang_jikp=cos_index[i]+njikp;
+                      if(ang_jikp>=cos_total) {
+                        printf("7 ang too big %7d\n",ang_jikp);
+                        exit(1);
+                      }
+                      nb_ikp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_pi) {
+                        new_n_tot=nb_pi+maxneigh;
+                        grow_pi(nb_pi,new_n_tot);
+                        nb_pi=new_n_tot;
+                      }
+                      bt_pi[nb_ikp].i=i;
+                      bt_pi[nb_ikp].j=kp;
+                      bt_pi[nb_ikp].temp=temp_ikp;
+                      betaCapSq2=pi_p[itype-1]*betaS[temp_ikp]*betaS[temp_ikp]
+                          -betaP[temp_ikp]*betaP[temp_ikp];
+                      dbetaCapSq2=2.0*pi_p[itype-1]*betaS[temp_ikp]*dBetaS[temp_ikp]
+                          -2.0*betaP[temp_ikp]*dBetaP[temp_ikp];
+                      dotV=(disij[0][temp_jk]*disij[0][temp_ikp]+disij[1][temp_jk]
+                          *disij[1][temp_ikp]+disij[2][temp_jk]*disij[2][temp_ikp])
+                          /(rij[temp_jk]*rij[temp_ikp]);
+                      cosSq1=cosAng[ang_jikp]*cosAng[ang_jikp];
+                      angFactor=dotV+cosAng[ang_jikp]*cosAng[ang_ijk];
+                      angRfactor=4.0*angFactor*dotV;
+                      dAngR1=-angRfactor/rij[temp_jk];
+                      dAngR2=-angRfactor/rij[temp_ikp];
+                      angFactor1=4.0*angFactor*cosAng[ang_jikp]
+                          +2.0*cosAng[ang_ijk]*(1.0-cosSq1);
+                      angFactor2=4.0*angFactor*cosAng[ang_ijk]
+                          +2.0*cosAng[ang_jikp]*(1.0-cosSq);
+                      angFactor3=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+                      betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//5th BB is 5th term of Eq. 38 (a) Eq. 21 (b) where i , k and k' =neighbors j
+
+                      BB=BB+betaCapSum*angFactor3;
+
+//app1 is derivative of BB 5th term w.r.t. cos(theta_ijk) 
+//app2 is derivative of BB 5th term w.r.t. cos(theta_jik') 
+//agpdpr1 is derivative of BB 5th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 5th term for atom j w.r.t. Beta(r_ik')
+//agpdpr3 is derivative of BB 5th term for atom j w.r.t. dot(r_ik',r_ij)
+
+                      app1=betaCapSum*angFactor1;
+                      app2=betaCapSum*angFactor2;
+                      agpdpr1=(.5*angFactor3*dbetaCapSq1*betaCapSq2
+                          +betaCapSum*dAngR1)/rij[temp_jk];
+                      agpdpr2=(.5*angFactor3*betaCapSq1*dbetaCapSq2
+                          +betaCapSum*dAngR2)/rij[temp_ikp];
+                      agpdpr3=4.0*betaCapSum*angFactor/(rij[temp_ikp]*rij[temp_jk]);
+
+                      bt_pi[nb_ij].dBB[0]+=
+                          +app2*dcAng[ang_jikp][0][ngl]
+                          -app1*dcAng[ang_ijk][0][ngi];
+                      bt_pi[nb_ij].dBB[1]+=
+                          +app2*dcAng[ang_jikp][1][ngl]
+                          -app1*dcAng[ang_ijk][1][ngi];
+                      bt_pi[nb_ij].dBB[2]+=
+                          +app2*dcAng[ang_jikp][2][ngl]
+                          -app1*dcAng[ang_ijk][2][ngi];
+                      bt_pi[nb_ikp].dBB[0]+=
+                          agpdpr2*disij[0][temp_ikp]
+                          +agpdpr3*disij[0][temp_jk]
+                          +app2*dcAng[ang_jikp][0][nglj];
+                      bt_pi[nb_ikp].dBB[1]+=
+                          agpdpr2*disij[1][temp_ikp]
+                          +agpdpr3*disij[1][temp_jk]
+                          +app2*dcAng[ang_jikp][1][nglj];
+                      bt_pi[nb_ikp].dBB[2]+=
+                          agpdpr2*disij[2][temp_ikp]
+                          +agpdpr3*disij[2][temp_jk]
+                          +app2*dcAng[ang_jikp][2][nglj];
+                      bt_pi[nb_jk].dBB[0]+=
+                          agpdpr1*disij[0][temp_jk]
+                          +agpdpr3*disij[0][temp_ikp]
+                          +app1*dcAng[ang_ijk][0][ngk];
+                      bt_pi[nb_jk].dBB[1]+=
+                          agpdpr1*disij[1][temp_jk]
+                          +agpdpr3*disij[1][temp_ikp]
+                          +app1*dcAng[ang_ijk][1][ngk];
+                      bt_pi[nb_jk].dBB[2]+=
+                          agpdpr1*disij[2][temp_jk]
+                          +agpdpr3*disij[2][temp_ikp]
+                          +app1*dcAng[ang_ijk][2][ngk];
+                    }
+                  }
+                }
+                if(pi_flag==0)
+                  nPiBk[n]=nPiBk[n]+1;
+              }
+            }
+          }
+          CC=betaP[temp_ij]*betaP[temp_ij]+pi_delta[iij]*pi_delta[iij];
+          BBrt=sqrt(BB+small6);
+          AB1=CC+pi_c[iij]*(AA+BBrt)+small7;
+          AB2=CC+pi_c[iij]*(AA-BBrt+sqrt(small6))+small7;
+          BBrtR=1.0/BBrt;
+          ABrtR1=1.0/sqrt(AB1);
+          ABrtR2=1.0/sqrt(AB2);
+
+// piB is similary formulation to (a) Eq. 36 and (b) Eq. 18
+
+          piB[n]=(ABrtR1+ABrtR2)*pi_a[iij]*betaP[temp_ij];
+          dPiB1=-.5*(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_c[iij]*pi_a[iij]*betaP[temp_ij];
+          dPiB2=.25*BBrtR*(pow(ABrtR2,3)-pow(ABrtR1,3))*pi_c[iij]*pi_a[iij]*betaP[temp_ij];
+          dPiB3=((ABrtR1+ABrtR2)*pi_a[iij]-(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_a[iij]
+              *betaP[temp_ij]*betaP[temp_ij])*dBetaP[temp_ij]/rij[temp_ij];
+          n++;
+          pp2=2.0*betaP[temp_ij];
+          for(m=0;m<nb_t;m++) {
+            bt_ij=bt_pi[m].temp;
+            bt_i=bt_pi[m].i;
+            bt_j=bt_pi[m].j;
+            for(pp=0;pp<3;pp++) { 
+              bt_pi[m].dPiB[pp]=
+                  +dPiB1*bt_pi[m].dAA[pp]
+                  +dPiB2*bt_pi[m].dBB[pp];
+              ftmp[pp]=pp2*bt_pi[m].dPiB[pp];
+              f[bt_i][pp]-=ftmp[pp];
+              f[bt_j][pp]+=ftmp[pp];
+           
+            }
+            if(evflag) {
+              ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                  ,ftmp[2],disij[0][bt_ij],disij[1][bt_ij],disij[2][bt_ij]);
+            }
+          }
+          for(pp=0;pp<3;pp++) { 
+            ftmp[pp]=pp2*dPiB3*disij[pp][temp_ij];
+            f[i][pp]-=ftmp[pp];
+            f[j][pp]+=ftmp[pp];
+          }
+          if(evflag) {
+            ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                ,ftmp[2],disij[0][temp_ij],disij[1][temp_ij],disij[2][temp_ij]);
+          }
+        }
+      }
+    }
+  }
+  destroy_pi();
+}
+
+void PairBOP::PiBo_otf()
+{
+  int new_n_tot;
+  int i,j,k,kp,m,n,pp,nb_t;
+  int iij,iik,iikp,ji,ki,ijkp,ijk;
+  int nsearch,ncmp;
+  int i_tag,j_tag;
+  int itmp,ltmp,jtmp,ktmp;
+  int pi_flag,ks;
+  int nlocal;
+  int inum,*ilist,*iilist,*jlist;
+  int **firstneigh,*numneigh; 
+  int itype,jtype,ktype,kptype;
+  int temp_ij,temp_ik,temp_ikp;
+  int temp_jk,temp_jkp;
+  int nb_ij,nb_ik,nb_jk,nb_ikp,nb_jkp;
+  int bt_i,bt_j;
+  double AA,BB,CC,DD,EE,FF;
+  double cosSq,sinFactor,cosFactor;
+  double cosSq1,dotV,BBrt,AB1,AB2;
+  double BBrtR,ABrtR,ABrtR1,ABrtR2;
+  double angFactor,angFactor1,angFactor2;
+  double angFactor3,angFactor4,angRfactor;
+  double dAngR1,dAngR2,agpdpr3;
+  double agpdpr1,agpdpr2,app1,app2,app3;
+  double betaCapSq1,dbetaCapSq1;
+  double betaCapSq2,dbetaCapSq2;
+  double betaCapSum,ps;
+  double ftmp[3],xtmp[3];
+  double dPiB1,dPiB2,dPiB3,pp2;
+
+  double dis_ij[3],rsq_ij,r_ij;
+  double betaP_ij,dBetaP_ij;
+  double dis_ik[3],rsq_ik,r_ik;
+  double betaS_ik,dBetaS_ik;
+  double betaP_ik,dBetaP_ik;
+  double dis_ikp[3],rsq_ikp,r_ikp;
+  double betaS_ikp,dBetaS_ikp;
+  double betaP_ikp,dBetaP_ikp;
+  double dis_jk[3],rsq_jk,r_jk;
+  double betaS_jk,dBetaS_jk;
+  double betaP_jk,dBetaP_jk;
+  double dis_jkp[3],rsq_jkp,r_jkp;
+  double betaS_jkp,dBetaS_jkp;
+  double betaP_jkp,dBetaP_jkp;
+
+  double cosAng_jik,dcA_jik[3][2];
+  double cosAng_jikp,dcA_jikp[3][2];
+  double cosAng_kikp,dcA_kikp[3][2];
+  double cosAng_ijk,dcA_ijk[3][2];
+  double cosAng_ijkp,dcA_ijkp[3][2];
+  double cosAng_kjkp,dcA_kjkp[3][2];
+
+  int newton_pair = force->newton_pair;
+
+  double **f = atom->f;
+  double **x = atom->x;
+  int *type = atom->type;
+  int *tag = atom->tag;
+
+  nlocal = atom->nlocal;
+  numneigh = list->numneigh;
+  firstneigh = list->firstneigh;
+  inum = list->inum;
+  ilist = list->ilist;
+  n=0;
+  if(nb_pi>16) {
+    nb_pi=16;
+  }
+  if(nb_pi==0) {
+    nb_pi=(maxneigh)*(maxneigh/2);
+  }
+
+// Loop over all local atoms for i
+
+  if(allocate_pi) {
+    destroy_pi();   
+  }
+  create_pi(nb_pi);   
+
+  for(itmp=0;itmp<inum;itmp++) {
+    nb_t=0;
+    i = ilist[itmp];
+    itype = map[type[i]]+1;
+    i_tag=tag[i];
+
+// j is a loop over all neighbors of i
+
+    iilist=firstneigh[i];
+    for(jtmp=0;jtmp<numneigh[i];jtmp++) {
+      for(m=0;m<nb_pi;m++) {
+        for(pp=0;pp<3;pp++) { 
+          bt_pi[m].dAA[pp]=0.0; 
+          bt_pi[m].dBB[pp]=0.0; 
+          bt_pi[m].dPiB[pp]=0.0; 
+        }
+        bt_pi[m].i=-1;
+        bt_pi[m].j=-1;
+      }
+      temp_ij=BOP_index[i]+jtmp;
+      j=iilist[jtmp];
+      jlist=firstneigh[j];
+      jtype=map[type[j]]+1;
+      j_tag=tag[j];
+      nb_t=0;
+      ftmp[0]=0.0;
+      ftmp[1]=0.0;
+      ftmp[2]=0.0;
+      if(j_tag>=i_tag) {
+        if(itype==jtype)
+          iij=itype-1;
+        else if(itype<jtype)
+          iij=itype*bop_types-itype*(itype+1)/2+jtype-1;
+        else
+          iij=jtype*bop_types-jtype*(jtype+1)/2+itype-1;
+        AA=0.0;
+        BB=0.0;
+        nPiBk[n]=0;
+        for(ji=0;ji<numneigh[j];ji++) {
+          if(x[jlist[ji]][0]==x[i][0]) {
+            if(x[jlist[ji]][1]==x[i][1]) {
+              if(x[jlist[ji]][2]==x[i][2]) {
+                  break;
+              }
+            }
+          }
+        }
+        nb_ij=nb_t;
+        nb_t++;
+        if(nb_t>nb_pi) {
+          new_n_tot=nb_pi+maxneigh;
+          grow_pi(nb_pi,new_n_tot);
+          nb_pi=new_n_tot;
+        }
+        bt_pi[nb_ij].i=i;
+        bt_pi[nb_ij].j=j;
+        bt_pi[nb_ij].temp=temp_ij;
+        dis_ij[0]=x[j][0]-x[i][0]; 
+        dis_ij[1]=x[j][1]-x[i][1]; 
+        dis_ij[2]=x[j][2]-x[i][2]; 
+        rsq_ij=dis_ij[0]*dis_ij[0]
+            +dis_ij[1]*dis_ij[1]
+            +dis_ij[2]*dis_ij[2];
+        r_ij=sqrt(rsq_ij); 
+        if(r_ij<=rcut[iij]) {
+          if(n>=neigh_total) {
+            printf("BOP 17:n is too large \n");
+            exit(1);
+          }
+          ps=r_ij*rdr[iij]+1.0;
+          ks=(int)ps;
+          if(nr-1<ks)
+            ks=nr-1;
+          ps=ps-ks;
+          if(ps>1.0)
+            ps=1.0;
+          betaP_ij=((pBetaP3[iij][ks-1]*ps+pBetaP2[iij][ks-1])*ps
+              +pBetaP1[iij][ks-1])*ps+pBetaP[iij][ks-1];
+          dBetaP_ij=(pBetaP6[iij][ks-1]*ps+pBetaP5[iij][ks-1])*ps
+              +pBetaP4[iij][ks-1];
+
+// j and k are different neighbors of i
+
+          for(ktmp=0;ktmp<numneigh[i];ktmp++) {
+            if(ktmp!=jtmp) {
+              temp_ik=BOP_index[i]+ktmp;
+              k=iilist[ktmp];
+              ktype=map[type[k]]+1;
+              if(itype==ktype) 
+                iik=itype-1;
+              else if(itype<ktype) 
+                iik=itype*bop_types-itype*(itype+1)/2+ktype-1;
+              else 
+                iik=ktype*bop_types-ktype*(ktype+1)/2+itype-1; 
+              dis_ik[0]=x[k][0]-x[i][0]; 
+              dis_ik[1]=x[k][1]-x[i][1]; 
+              dis_ik[2]=x[k][2]-x[i][2]; 
+              rsq_ik=dis_ik[0]*dis_ik[0]
+                  +dis_ik[1]*dis_ik[1]
+                  +dis_ik[2]*dis_ik[2];
+              r_ik=sqrt(rsq_ik);
+              if(r_ik<=rcut[iik]) {
+                ps=r_ik*rdr[iik]+1.0;
+                ks=(int)ps;
+                if(nr-1<ks)
+                  ks=nr-1;
+                ps=ps-ks;
+                if(ps>1.0)
+                  ps=1.0;
+                betaS_ik=((pBetaS3[iik][ks-1]*ps+pBetaS2[iik][ks-1])*ps
+                    +pBetaS1[iik][ks-1])*ps+pBetaS[iik][ks-1];
+                dBetaS_ik=(pBetaS6[iik][ks-1]*ps+pBetaS5[iik][ks-1])*ps
+                    +pBetaS4[iik][ks-1];
+                betaP_ik=((pBetaP3[iik][ks-1]*ps+pBetaP2[iik][ks-1])*ps
+                    +pBetaP1[iik][ks-1])*ps+pBetaP[iik][ks-1];
+                dBetaP_ik=(pBetaP6[iik][ks-1]*ps+pBetaP5[iik][ks-1])*ps
+                    +pBetaP4[iik][ks-1];
+                cosAng_jik=(dis_ij[0]*dis_ik[0]+dis_ij[1]*dis_ik[1]
+                    +dis_ij[2]*dis_ik[2])/(r_ij*r_ik); 
+                dcA_jik[0][0]=(dis_ik[0]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[0]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[1][0]=(dis_ik[1]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[1]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[2][0]=(dis_ik[2]*r_ij*r_ik-cosAng_jik
+                    *dis_ij[2]*r_ik*r_ik)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[0][1]=(dis_ij[0]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[0]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[1][1]=(dis_ij[1]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[1]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                dcA_jik[2][1]=(dis_ij[2]*r_ij*r_ik-cosAng_jik
+                    *dis_ik[2]*r_ij*r_ij)/(r_ij*r_ij*r_ik*r_ik);
+                nb_ik=nb_t;
+                nb_t++;
+                if(nb_t>nb_pi) {
+                  new_n_tot=nb_pi+maxneigh;
+                  grow_pi(nb_pi,new_n_tot);
+                  nb_pi=new_n_tot;
+                }
+                bt_pi[nb_ik].i=i;
+                bt_pi[nb_ik].j=k;
+                bt_pi[nb_ik].temp=temp_ik;
+                cosSq=cosAng_jik*cosAng_jik;
+                sinFactor=.5*(1.0-cosSq)*pi_p[itype-1]*betaS_ik;
+                cosFactor=.5*(1.0+cosSq)*betaP_ik;
+                betaCapSq1=pi_p[itype-1]*betaS_ik*betaS_ik-betaP_ik
+                    *betaP_ik;
+                dbetaCapSq1=2.0*pi_p[itype-1]*betaS_ik*dBetaS_ik
+                    -2.0*betaP_ik*dBetaP_ik;
+
+//AA is Eq. 37 (a) and Eq. 19 (b) or i atoms 
+//1st BB is first term of Eq. 38 (a) where j and k =neighbors i
+
+                AA=AA+sinFactor*betaS_ik+cosFactor*betaP_ik;
+                BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+//agpdpr1 is derivative of AA w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//app1 is derivative of AA w.r.t. for atom i w.r.t. cos(theta_jik)
+//app2 is derivative of BB w.r.t. for atom i w.r.t. cos(theta_jik)
+
+                agpdpr1=(2.0*sinFactor*dBetaS_ik+2.0*cosFactor
+                    *dBetaP_ik)/r_ik;
+                app1=cosAng_jik*(-pi_p[itype-1]*betaS_ik*betaS_ik
+                    +betaP_ik*betaP_ik);
+                app2=-(1.0-cosSq)*cosAng_jik*betaCapSq1*betaCapSq1;
+                agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/r_ik;
+                if((nPiBk[n]>=neigh_ct)) {
+                  printf("BOP 14:7 itypeSigBk error exit \n");
+                  exit(1);
+                }
+                itypePiBk[n][nPiBk[n]]=k;
+                bt_pi[nb_ij].dAA[0]+=
+                    app1*dcA_jik[0][0];
+                bt_pi[nb_ij].dAA[1]+=
+                    app1*dcA_jik[1][0];
+                bt_pi[nb_ij].dAA[2]+=
+                    app1*dcA_jik[2][0];
+                bt_pi[nb_ij].dBB[0]+=
+                    app2*dcA_jik[0][0];
+                bt_pi[nb_ij].dBB[1]+=
+                    app2*dcA_jik[1][0];
+                bt_pi[nb_ij].dBB[2]+=
+                    app2*dcA_jik[2][0];
+                bt_pi[nb_ik].dAA[0]+=
+                    agpdpr1*dis_ik[0]
+                    +app1*dcA_jik[0][1];
+                bt_pi[nb_ik].dAA[1]+=
+                    agpdpr1*dis_ik[1]
+                    +app1*dcA_jik[1][1];
+                bt_pi[nb_ik].dAA[2]+=
+                    agpdpr1*dis_ik[2]
+                    +app1*dcA_jik[2][1];
+                bt_pi[nb_ik].dBB[0]+=
+                    app2*dcA_jik[0][1]
+                    +agpdpr2*dis_ik[0];
+                bt_pi[nb_ik].dBB[1]+=
+                    app2*dcA_jik[1][1]
+                    +agpdpr2*dis_ik[1];
+                bt_pi[nb_ik].dBB[2]+=
+                    app2*dcA_jik[2][1]
+                    +agpdpr2*dis_ik[2];
+
+// j and k and k' are different neighbors of i 
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=jtmp) {
+                    temp_ikp=BOP_index[i]+ltmp;
+                    kp=iilist[ltmp];
+                    kptype=map[type[kp]]+1;
+                    if((nPiBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                      ncmp=itypePiBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    if(itype==kptype)
+                      iikp=itype-1;
+                    else if(itype<kptype)
+                      iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+                    else
+                      iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+                    dis_ikp[0]=x[kp][0]-x[i][0]; 
+                    dis_ikp[1]=x[kp][1]-x[i][1]; 
+                    dis_ikp[2]=x[kp][2]-x[i][2]; 
+                    rsq_ikp=dis_ikp[0]*dis_ikp[0]
+                        +dis_ikp[1]*dis_ikp[1]
+                        +dis_ikp[2]*dis_ikp[2];
+                    r_ikp=sqrt(rsq_ikp);
+                    if(r_ikp<=rcut[iikp]) {
+                      ps=r_ikp*rdr[iikp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+                          +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+                      dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+                          +pBetaS4[iikp][ks-1];
+                      betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+                          +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+                      dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+                          +pBetaP4[iikp][ks-1];
+                      cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+                          +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp); 
+                      dcA_jikp[0][0]=(dis_ikp[0]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[0]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[1][0]=(dis_ikp[1]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[1]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[2][0]=(dis_ikp[2]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[2]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[0][1]=(dis_ij[0]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[0]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[1][1]=(dis_ij[1]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[1]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[2][1]=(dis_ij[2]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[2]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      cosAng_kikp=(dis_ik[0]*dis_ikp[0]+dis_ik[1]*dis_ikp[1]
+                          +dis_ik[2]*dis_ikp[2])/(r_ik*r_ikp); 
+                      dcA_kikp[0][0]=(dis_ikp[0]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ik[0]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[1][0]=(dis_ikp[1]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ik[1]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[2][0]=(dis_ikp[2]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ik[2]*r_ikp*r_ikp)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[0][1]=(dis_ik[0]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ikp[0]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[1][1]=(dis_ik[1]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ikp[1]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+                      dcA_kikp[2][1]=(dis_ik[2]*r_ik*r_ikp-cosAng_kikp
+                          *dis_ikp[2]*r_ik*r_ik)/(r_ik*r_ik*r_ikp*r_ikp);
+                      nb_ikp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_pi) {
+                        new_n_tot=nb_pi+maxneigh;
+                        grow_pi(nb_pi,new_n_tot);
+                        nb_pi=new_n_tot;
+                      }
+                      bt_pi[nb_ikp].i=i;
+                      bt_pi[nb_ikp].j=kp;
+                      bt_pi[nb_ikp].temp=temp_ikp;
+                      betaCapSq2=pi_p[itype-1]*betaS_ikp*betaS_ikp
+                          -betaP_ikp*betaP_ikp;
+                      dbetaCapSq2=2.0*pi_p[itype-1]*betaS_ikp*dBetaS_ikp
+                          -2.0*betaP_ikp*dBetaP_ikp;
+                      cosSq1=cosAng_jikp*cosAng_jikp;
+                      angFactor=cosAng_kikp-cosAng_jikp*cosAng_jik;
+                      angFactor1=4.0*angFactor;
+                      angFactor2=-angFactor1*cosAng_jikp
+                          +2.0*cosAng_jik*(1.0-cosSq1);
+                      angFactor3=-angFactor1*cosAng_jik
+                          +2.0*cosAng_jikp*(1.0-cosSq);
+                      angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+                      betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//2nd BB is third term of Eq. 38 (a) where j , k and k'=neighbors i
+
+                      BB=BB+betaCapSum*angFactor4;
+
+//agpdpr1 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik)
+//agpdpr2 is derivative of BB w.r.t. for atom i w.r.t. Beta(r_ik')
+//app1 is derivative of BB 3rd term w.r.t. cos(theta_kik')
+//app2 is derivative of BB 3rd term w.r.t. cos(theta_jik)
+//app3 is derivative of BB 3rd term w.r.t. cos(theta_jik')
+
+                      app1=betaCapSum*angFactor1;
+                      app2=betaCapSum*angFactor2;
+                      app3=betaCapSum*angFactor3;
+                      agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/r_ik;
+                      agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/r_ikp;
+                      bt_pi[nb_ij].dBB[0]+=
+                          app2*dcA_jik[0][0]
+                          +app3*dcA_jikp[0][0]; 
+                      bt_pi[nb_ij].dBB[1]+=
+                          app2*dcA_jik[1][0]
+                          +app3*dcA_jikp[1][0]; 
+                      bt_pi[nb_ij].dBB[2]+=
+                          app2*dcA_jik[2][0]
+                          +app3*dcA_jikp[2][0]; 
+                      bt_pi[nb_ik].dBB[0]+=
+                          agpdpr1*dis_ik[0]
+                          +app1*dcA_kikp[0][0]
+                          +app2*dcA_jik[0][1];
+                      bt_pi[nb_ik].dBB[1]+=
+                          agpdpr1*dis_ik[1]
+                          +app1*dcA_kikp[1][0]
+                          +app2*dcA_jik[1][1];
+                      bt_pi[nb_ik].dBB[2]+=
+                          agpdpr1*dis_ik[2]
+                          +app1*dcA_kikp[2][0]
+                          +app2*dcA_jik[2][1];
+                      bt_pi[nb_ikp].dBB[0]+=
+                          agpdpr2*dis_ikp[0]
+                          +app1*dcA_kikp[0][1]
+                          +app3*dcA_jikp[0][1];
+                      bt_pi[nb_ikp].dBB[1]+=
+                          agpdpr2*dis_ikp[1]
+                          +app1*dcA_kikp[1][1]
+                          +app3*dcA_jikp[1][1];
+                      bt_pi[nb_ikp].dBB[2]+=
+                          agpdpr2*dis_ikp[2]
+                          +app1*dcA_kikp[2][1]
+                          +app3*dcA_jikp[2][1];
+                      }
+                    }
+                  }
+                nPiBk[n]=nPiBk[n]+1;
+                }
+              }
+            }
+
+//j is a neighbor of i and k is a neighbor of j and equal to i
+
+          for(ki=0;ki<numneigh[j];ki++) {
+            k=jlist[ki];
+            if(x[k][0]==x[i][0]) {
+              if(x[k][1]==x[i][1]) {
+                if(x[k][2]==x[i][2]) {
+                  break;
+                }
+              }
+            }
+          }
+
+//j is a neighbor of i and k is a neighbor of j not equal to i
+
+          for(ktmp=0;ktmp<numneigh[j];ktmp++) {
+            if(ktmp!=ki) {
+              temp_jk=BOP_index[j]+ktmp;
+              k=jlist[ktmp];
+              ktype=map[type[k]]+1;
+              pi_flag=0;
+              if((nPiBk[n]>neigh_ct)) {
+                printf("BOP 14:7 itypeSigBk error exit \n");
+                exit(1);
+              }
+              for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                ncmp=itypePiBk[n][nsearch];
+                if(x[ncmp][0]==x[k][0]) {
+                  if(x[ncmp][1]==x[k][1]) {
+                    if(x[ncmp][2]==x[k][2]) {
+                      pi_flag=1;
+                      break;
+                    } 
+                  } 
+                } 
+              } 
+              if(pi_flag==0) {
+                if((nPiBk[n]>=neigh_ct)) {
+                  printf("BOP 14:7 itypeSigBk error exit \n");
+                  exit(1);
+                }
+                itypePiBk[n][nPiBk[n]]=k;
+              } 
+              if(jtype==ktype) 
+                ijk=jtype-1;
+              else if(jtype<ktype)
+                ijk=jtype*bop_types-jtype*(jtype+1)/2+ktype-1;
+              else
+                ijk=ktype*bop_types-ktype*(ktype+1)/2+jtype-1;
+              dis_jk[0]=x[k][0]-x[j][0]; 
+              dis_jk[1]=x[k][1]-x[j][1]; 
+              dis_jk[2]=x[k][2]-x[j][2]; 
+              rsq_jk=dis_jk[0]*dis_jk[0]
+                  +dis_jk[1]*dis_jk[1]
+                  +dis_jk[2]*dis_jk[2];
+              r_jk=sqrt(rsq_jk); 
+              if(r_jk<=rcut[ijk]) { 
+                ps=r_jk*rdr[ijk]+1.0;
+                ks=(int)ps;
+                if(nr-1<ks)
+                  ks=nr-1;
+                ps=ps-ks;
+                if(ps>1.0)
+                  ps=1.0;
+                betaS_jk=((pBetaS3[ijk][ks-1]*ps+pBetaS2[ijk][ks-1])*ps
+                    +pBetaS1[ijk][ks-1])*ps+pBetaS[ijk][ks-1];
+                dBetaS_jk=(pBetaS6[ijk][ks-1]*ps+pBetaS5[ijk][ks-1])*ps
+                    +pBetaS4[ijk][ks-1];
+                betaP_jk=((pBetaP3[ijk][ks-1]*ps+pBetaP2[ijk][ks-1])*ps
+                    +pBetaP1[ijk][ks-1])*ps+pBetaP[ijk][ks-1];
+                dBetaP_jk=(pBetaP6[ijk][ks-1]*ps+pBetaP5[ijk][ks-1])*ps
+                    +pBetaP4[ijk][ks-1];
+                cosAng_ijk=(-dis_ij[0]*dis_jk[0]-dis_ij[1]*dis_jk[1]
+                    -dis_ij[2]*dis_jk[2])/(r_ij*r_jk); 
+                dcA_ijk[0][0]=(dis_jk[0]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[0]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[1][0]=(dis_jk[1]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[1]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[2][0]=(dis_jk[2]*r_ij*r_jk-cosAng_ijk
+                    *-dis_ij[2]*r_jk*r_jk)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[0][1]=(-dis_ij[0]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[0]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[1][1]=(-dis_ij[1]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[1]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                dcA_ijk[2][1]=(-dis_ij[2]*r_ij*r_jk-cosAng_ijk
+                    *dis_jk[2]*r_ij*r_ij)/(r_ij*r_ij*r_jk*r_jk);
+                nb_jk=nb_t;
+                nb_t++;
+                if(nb_t>nb_pi) {
+                  new_n_tot=nb_pi+maxneigh;
+                  grow_pi(nb_pi,new_n_tot);
+                  nb_pi=new_n_tot;
+                }
+                bt_pi[nb_jk].i=j;
+                bt_pi[nb_jk].j=k;
+                bt_pi[nb_jk].temp=temp_jk;
+                cosSq=cosAng_ijk*cosAng_ijk;
+                sinFactor=.5*(1.0-cosSq)*pi_p[jtype-1]*betaS_jk;
+                cosFactor=.5*(1.0+cosSq)*betaP_jk;
+                betaCapSq1=pi_p[jtype-1]*betaS_jk*betaS_jk
+                    -betaP_jk*betaP_jk;
+                dbetaCapSq1=2.0*pi_p[jtype-1]*betaS_jk*dBetaS_jk
+                    -2.0*betaP_jk*dBetaP_jk;
+
+//AA is Eq. 37 (a) and Eq. 19 (b) for j atoms 
+//3rd BB is 2nd term of Eq. 38 (a) where i and k =neighbors j
+
+                AA=AA+sinFactor*betaS_jk+cosFactor*betaP_jk;
+                BB=BB+.25*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*betaCapSq1;
+
+                agpdpr1=(2.0*sinFactor*dBetaS_jk+2.0*cosFactor
+                    *dBetaP_jk)/r_jk;
+
+//agpdpr1 is derivative of AA for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB for atom j w.r.t. Beta(r_jk)
+//app1 is derivative of AA for j atom w.r.t. cos(theta_ijk)
+//app2 is derivative of BB 2nd term w.r.t. cos(theta_ijk) 
+
+                agpdpr2=.5*(1.0-cosSq)*(1.0-cosSq)*betaCapSq1*dbetaCapSq1/r_jk;
+                app1=cosAng_ijk*(-pi_p[jtype-1]*betaS_jk*betaS_jk
+                    +betaP_jk*betaP_jk);
+                app2=-(1.0-cosSq)*cosAng_ijk*betaCapSq1*betaCapSq1;
+                bt_pi[nb_ij].dAA[0]-=
+                    app1*dcA_ijk[0][0];
+                bt_pi[nb_ij].dAA[1]-=
+                    app1*dcA_ijk[1][0];
+                bt_pi[nb_ij].dAA[2]-=
+                    app1*dcA_ijk[2][0];
+                bt_pi[nb_ij].dBB[0]-=
+                    app2*dcA_ijk[0][0];
+                bt_pi[nb_ij].dBB[1]-=
+                    app2*dcA_ijk[1][0];
+                bt_pi[nb_ij].dBB[2]-=
+                    app2*dcA_ijk[2][0];
+                bt_pi[nb_jk].dAA[0]+=
+                    agpdpr1*dis_jk[0]
+                    +app1*dcA_ijk[0][1];
+                bt_pi[nb_jk].dAA[1]+=
+                    agpdpr1*dis_jk[1]
+                    +app1*dcA_ijk[1][1];
+                bt_pi[nb_jk].dAA[2]+=
+                    agpdpr1*dis_jk[2]
+                    +app1*dcA_ijk[2][1];
+                bt_pi[nb_jk].dBB[0]+=
+                    app2*dcA_ijk[0][1]
+                    +agpdpr2*dis_jk[0];
+                bt_pi[nb_jk].dBB[1]+=
+                    app2*dcA_ijk[1][1]
+                    +agpdpr2*dis_jk[1];
+                bt_pi[nb_jk].dBB[2]+=
+                    app2*dcA_ijk[2][1]
+                    +agpdpr2*dis_jk[2];
+            
+//j is a neighbor of i and k and k' are different neighbors of j not equal to i
+
+                for(ltmp=0;ltmp<ktmp;ltmp++) {
+                  if(ltmp!=ki) {
+                    temp_jkp=BOP_index[j]+ltmp;
+                    kp=jlist[ltmp];
+                    kptype=map[type[kp]]+1;
+                    if((nPiBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                      ncmp=itypePiBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    if(jtype==kptype)
+                      ijkp=jtype-1;
+                    else if(jtype<kptype)
+                      ijkp=jtype*bop_types-jtype*(jtype+1)/2+kptype-1;
+                    else
+                      ijkp=kptype*bop_types-kptype*(kptype+1)/2+jtype-1;
+                    dis_jkp[0]=x[kp][0]-x[j][0]; 
+                    dis_jkp[1]=x[kp][1]-x[j][1]; 
+                    dis_jkp[2]=x[kp][2]-x[j][2]; 
+                    rsq_jkp=dis_jkp[0]*dis_jkp[0]
+                        +dis_jkp[1]*dis_jkp[1]
+                        +dis_jkp[2]*dis_jkp[2];
+                    r_jkp=sqrt(rsq_jkp); 
+                    if(r_jkp<=rcut[ijkp]) {
+                      ps=r_jkp*rdr[ijkp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_jkp=((pBetaS3[ijkp][ks-1]*ps+pBetaS2[ijkp][ks-1])*ps
+                          +pBetaS1[ijkp][ks-1])*ps+pBetaS[ijkp][ks-1];
+                      dBetaS_jkp=(pBetaS6[ijkp][ks-1]*ps+pBetaS5[ijkp][ks-1])*ps
+                          +pBetaS4[ijkp][ks-1];
+                      betaP_jkp=((pBetaP3[ijkp][ks-1]*ps+pBetaP2[ijkp][ks-1])*ps
+                          +pBetaP1[ijkp][ks-1])*ps+pBetaP[ijkp][ks-1];
+                      dBetaP_jkp=(pBetaP6[ijkp][ks-1]*ps+pBetaP5[ijkp][ks-1])*ps
+                          +pBetaP4[ijkp][ks-1];
+                      cosAng_ijkp=(-dis_ij[0]*dis_jkp[0]-dis_ij[1]*dis_jkp[1]
+                          -dis_ij[2]*dis_jkp[2])/(r_ij*r_jkp); 
+                      dcA_ijkp[0][0]=(dis_jkp[0]*r_ij*r_jkp-cosAng_ijkp
+                          *-dis_ij[0]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][0]=(dis_jkp[1]*r_ij*r_jkp-cosAng_ijkp
+                          *-dis_ij[1]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][0]=(dis_jkp[2]*r_ij*r_jkp-cosAng_ijkp
+                          *-dis_ij[2]*r_jkp*r_jkp)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[0][1]=(-dis_ij[0]*r_ij*r_jkp-cosAng_ijkp
+                          *dis_jkp[0]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[1][1]=(-dis_ij[1]*r_ij*r_jkp-cosAng_ijkp
+                          *dis_jkp[1]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      dcA_ijkp[2][1]=(-dis_ij[2]*r_ij*r_jkp-cosAng_ijkp
+                          *dis_jkp[2]*r_ij*r_ij)/(r_ij*r_ij*r_jkp*r_jkp);
+                      cosAng_kjkp=(dis_jk[0]*dis_jkp[0]+dis_jk[1]*dis_jkp[1]
+                          +dis_jk[2]*dis_jkp[2])/(r_jk*r_jkp); 
+                      dcA_kjkp[0][0]=(dis_jkp[0]*r_jk*r_jkp-cosAng_kjkp
+                          *dis_jk[0]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[1][0]=(dis_jkp[1]*r_jk*r_jkp-cosAng_kjkp
+                          *dis_jk[1]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[2][0]=(dis_jkp[2]*r_jk*r_jkp-cosAng_kjkp
+                          *dis_jk[2]*r_jkp*r_jkp)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[0][1]=(dis_jk[0]*r_jk*r_jkp-cosAng_kjkp
+                          *dis_jkp[0]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[1][1]=(dis_jk[1]*r_jk*r_jkp-cosAng_kjkp
+                          *dis_jkp[1]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      dcA_kjkp[2][1]=(dis_jk[2]*r_jk*r_jkp-cosAng_kjkp
+                          *dis_jkp[2]*r_jk*r_jk)/(r_jk*r_jk*r_jkp*r_jkp);
+                      nb_jkp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_pi) {
+                        new_n_tot=nb_pi+maxneigh;
+                        grow_pi(nb_pi,new_n_tot);
+                        nb_pi=new_n_tot;
+                      }
+                    bt_pi[nb_jkp].i=j;
+                    bt_pi[nb_jkp].j=kp;
+                    bt_pi[nb_jkp].temp=temp_jkp;
+                    betaCapSq2=pi_p[jtype-1]*betaS_jkp*betaS_jkp
+                      -betaP_jkp*betaP_jkp;
+                    dbetaCapSq2=2.0*pi_p[jtype-1]*betaS_jkp*dBetaS_jkp
+                      -2.0*betaP_jkp*dBetaP_jkp;
+                    cosSq1=cosAng_ijkp*cosAng_ijkp;
+                    angFactor=cosAng_kjkp-cosAng_ijkp*cosAng_ijk;
+                    angFactor1=4.0*angFactor;
+                    angFactor2=-angFactor1*cosAng_ijkp
+                      +2.0*cosAng_ijk*(1.0-cosSq1);
+                    angFactor3=-angFactor1*cosAng_ijk
+                      +2.0*cosAng_ijkp*(1.0-cosSq);
+                    angFactor4=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+                      betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//4th BB is 4th term of Eq. 38 (a) where i , k and k' =neighbors j
+
+                    BB=BB+betaCapSum*angFactor4;
+
+//app1 is derivative of BB 4th term w.r.t. cos(theta_kjk') 
+//app2 is derivative of BB 4th term w.r.t. cos(theta_ijk) 
+//app3 is derivative of BB 4th term w.r.t. cos(theta_ijk') 
+//agpdpr1 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 4th term for atom j w.r.t. Beta(r_jk')
+
+                    app1=betaCapSum*angFactor1;
+                    app2=betaCapSum*angFactor2;
+                    app3=betaCapSum*angFactor3;
+                    agpdpr1=.5*angFactor4*dbetaCapSq1*betaCapSq2/r_jk;
+                    agpdpr2=.5*angFactor4*betaCapSq1*dbetaCapSq2/r_jkp;
+                    bt_pi[nb_ij].dBB[0]-=
+                      app3*dcA_ijkp[0][0]
+                      +app2*dcA_ijk[0][0]; 
+                    bt_pi[nb_ij].dBB[1]-=
+                      app3*dcA_ijkp[1][0]
+                      +app2*dcA_ijk[1][0]; 
+                    bt_pi[nb_ij].dBB[2]-=
+                      app3*dcA_ijkp[2][0]
+                      +app2*dcA_ijk[2][0]; 
+                    bt_pi[nb_jk].dBB[0]+=
+                      agpdpr1*dis_jk[0]
+                      +app1*dcA_kjkp[0][0]
+                      +app2*dcA_ijk[0][1];
+                    bt_pi[nb_jk].dBB[1]+=
+                      agpdpr1*dis_jk[1]
+                      +app1*dcA_kjkp[1][0]
+                      +app2*dcA_ijk[1][1];
+                    bt_pi[nb_jk].dBB[2]+=
+                      agpdpr1*dis_jk[2]
+                      +app1*dcA_kjkp[2][0]
+                      +app2*dcA_ijk[2][1];
+                    bt_pi[nb_jkp].dBB[0]+=
+                      agpdpr2*dis_jkp[0]
+                      +app1*dcA_kjkp[0][1]
+                      +app3*dcA_ijkp[0][1];
+                    bt_pi[nb_jkp].dBB[1]+=
+                      agpdpr2*dis_jkp[1]
+                      +app1*dcA_kjkp[1][1]
+                      +app3*dcA_ijkp[1][1];
+                    bt_pi[nb_jkp].dBB[2]+=
+                      agpdpr2*dis_jkp[2]
+                      +app1*dcA_kjkp[2][1]
+                      +app3*dcA_ijkp[2][1];
+                    }
+                  }
+                }
+
+//j and k' are different neighbors of i and k is a neighbor of j not equal to i
+
+                for(ltmp=0;ltmp<numneigh[i];ltmp++) {
+                  if(ltmp!=jtmp) {
+                    temp_ikp=BOP_index[i]+ltmp;
+                    kp=iilist[ltmp];
+                    kptype=map[type[kp]]+1;
+                    if((nPiBk[n]>neigh_ct)) {
+                      printf("BOP 14:7 itypeSigBk error exit \n");
+                      exit(1);
+                    }
+                    for(nsearch=0;nsearch<nPiBk[n];nsearch++) {
+                      ncmp=itypePiBk[n][nsearch];
+                      if(x[ncmp][0]==x[kp][0]) {
+                        if(x[ncmp][1]==x[kp][1]) {
+                          if(x[ncmp][2]==x[kp][2]) {
+                            break;
+                          }
+                        }
+                      }
+                    }
+                    if(itype==kptype)
+                      iikp=itype-1;
+                    else if(itype<kptype)
+                      iikp=itype*bop_types-itype*(itype+1)/2+kptype-1;
+                    else
+                      iikp=kptype*bop_types-kptype*(kptype+1)/2+itype-1;
+                    dis_ikp[0]=x[kp][0]-x[i][0]; 
+                    dis_ikp[1]=x[kp][1]-x[i][1]; 
+                    dis_ikp[2]=x[kp][2]-x[i][2]; 
+                    rsq_ikp=dis_ikp[0]*dis_ikp[0]
+                        +dis_ikp[1]*dis_ikp[1]
+                        +dis_ikp[2]*dis_ikp[2];
+                    r_ikp=sqrt(rsq_ikp); 
+                    if(r_ikp<=rcut[iikp]) {
+                      ps=r_ikp*rdr[iikp]+1.0;
+                      ks=(int)ps;
+                      if(nr-1<ks)
+                        ks=nr-1;
+                      ps=ps-ks;
+                      if(ps>1.0)
+                        ps=1.0;
+                      betaS_ikp=((pBetaS3[iikp][ks-1]*ps+pBetaS2[iikp][ks-1])*ps
+                          +pBetaS1[iikp][ks-1])*ps+pBetaS[iikp][ks-1];
+                      dBetaS_ikp=(pBetaS6[iikp][ks-1]*ps+pBetaS5[iikp][ks-1])*ps
+                          +pBetaS4[iikp][ks-1];
+                      betaP_ikp=((pBetaP3[iikp][ks-1]*ps+pBetaP2[iikp][ks-1])*ps
+                          +pBetaP1[iikp][ks-1])*ps+pBetaP[iikp][ks-1];
+                      dBetaP_ikp=(pBetaP6[iikp][ks-1]*ps+pBetaP5[iikp][ks-1])*ps
+                          +pBetaP4[iikp][ks-1];
+                      cosAng_jikp=(dis_ij[0]*dis_ikp[0]+dis_ij[1]*dis_ikp[1]
+                          +dis_ij[2]*dis_ikp[2])/(r_ij*r_ikp); 
+                      dcA_jikp[0][0]=(dis_ikp[0]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[0]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[1][0]=(dis_ikp[1]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[1]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[2][0]=(dis_ikp[2]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ij[2]*r_ikp*r_ikp)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[0][1]=(dis_ij[0]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[0]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[1][1]=(dis_ij[1]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[1]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      dcA_jikp[2][1]=(dis_ij[2]*r_ij*r_ikp-cosAng_jikp
+                          *dis_ikp[2]*r_ij*r_ij)/(r_ij*r_ij*r_ikp*r_ikp);
+                      nb_ikp=nb_t;
+                      nb_t++;
+                      if(nb_t>nb_pi) {
+                        new_n_tot=nb_pi+maxneigh;
+                        grow_pi(nb_pi,new_n_tot);
+                        nb_pi=new_n_tot;
+                      }
+                      bt_pi[nb_ikp].i=i;
+                      bt_pi[nb_ikp].j=kp;
+                      bt_pi[nb_ikp].temp=temp_ikp;
+                
+                      betaCapSq2=pi_p[itype-1]*betaS_ikp*betaS_ikp
+                          -betaP_ikp*betaP_ikp;
+                      dbetaCapSq2=2.0*pi_p[itype-1]*betaS_ikp*dBetaS_ikp
+                          -2.0*betaP_ikp*dBetaP_ikp;
+                      dotV=(dis_jk[0]*dis_ikp[0]+dis_jk[1]
+                          *dis_ikp[1]+dis_jk[2]*dis_ikp[2])
+                          /(r_jk*r_ikp);
+                      cosSq1=cosAng_jikp*cosAng_jikp;
+                      angFactor=dotV+cosAng_jikp*cosAng_ijk;
+                      angRfactor=4.0*angFactor*dotV;
+                      dAngR1=-angRfactor/r_jk;
+                      dAngR2=-angRfactor/r_ikp;
+                      angFactor1=4.0*angFactor*cosAng_jikp
+                          +2.0*cosAng_ijk*(1.0-cosSq1);
+                      angFactor2=4.0*angFactor*cosAng_ijk
+                          +2.0*cosAng_jikp*(1.0-cosSq);
+                      angFactor3=2.0*angFactor*angFactor-(1.0-cosSq)*(1.0-cosSq1);
+                      betaCapSum=.5*betaCapSq1*betaCapSq2;
+
+//5th BB is 5th term of Eq. 38 (a) Eq. 21 (b) where i , k and k' =neighbors j
+
+                      BB=BB+betaCapSum*angFactor3;
+
+//app1 is derivative of BB 5th term w.r.t. cos(theta_ijk) 
+//app2 is derivative of BB 5th term w.r.t. cos(theta_jik') 
+//agpdpr1 is derivative of BB 5th term for atom j w.r.t. Beta(r_jk)
+//agpdpr2 is derivative of BB 5th term for atom j w.r.t. Beta(r_ik')
+//agpdpr3 is derivative of BB 5th term for atom j w.r.t. dot(r_ik',r_ij)
+
+                      app1=betaCapSum*angFactor1;
+                      app2=betaCapSum*angFactor2;
+                      agpdpr1=(.5*angFactor3*dbetaCapSq1*betaCapSq2
+                          +betaCapSum*dAngR1)/r_jk;
+                      agpdpr2=(.5*angFactor3*betaCapSq1*dbetaCapSq2
+                          +betaCapSum*dAngR2)/r_ikp;
+                      agpdpr3=4.0*betaCapSum*angFactor/(r_ikp*r_jk);
+                      bt_pi[nb_ij].dBB[0]+=
+                          +app2*dcA_jikp[0][0]
+                          -app1*dcA_ijk[0][0];
+                      bt_pi[nb_ij].dBB[1]+=
+                          +app2*dcA_jikp[1][0]
+                          -app1*dcA_ijk[1][0];
+                      bt_pi[nb_ij].dBB[2]+=
+                          +app2*dcA_jikp[2][0]
+                          -app1*dcA_ijk[2][0];
+                      bt_pi[nb_ikp].dBB[0]+=
+                          agpdpr2*dis_ikp[0]
+                          +agpdpr3*dis_jk[0]
+                          +app2*dcA_jikp[0][1];
+                      bt_pi[nb_ikp].dBB[1]+=
+                          agpdpr2*dis_ikp[1]
+                          +agpdpr3*dis_jk[1]
+                          +app2*dcA_jikp[1][1];
+                      bt_pi[nb_ikp].dBB[2]+=
+                          agpdpr2*dis_ikp[2]
+                          +agpdpr3*dis_jk[2]
+                          +app2*dcA_jikp[2][1];
+                      bt_pi[nb_jk].dBB[0]+=
+                          agpdpr1*dis_jk[0]
+                          +agpdpr3*dis_ikp[0]
+                          +app1*dcA_ijk[0][1];
+                      bt_pi[nb_jk].dBB[1]+=
+                          agpdpr1*dis_jk[1]
+                          +agpdpr3*dis_ikp[1]
+                          +app1*dcA_ijk[1][1];
+                      bt_pi[nb_jk].dBB[2]+=
+                          agpdpr1*dis_jk[2]
+                          +agpdpr3*dis_ikp[2]
+                          +app1*dcA_ijk[2][1];
+                    }
+                  }
+                }
+                if(pi_flag==0)
+                  nPiBk[n]=nPiBk[n]+1;
+              }
+            }
+          }
+          CC=betaP_ij*betaP_ij+pi_delta[iij]*pi_delta[iij];
+          BBrt=sqrt(BB+small6);
+          AB1=CC+pi_c[iij]*(AA+BBrt)+small7;
+          AB2=CC+pi_c[iij]*(AA-BBrt+sqrt(small6))+small7;
+          BBrtR=1.0/BBrt;
+          ABrtR1=1.0/sqrt(AB1);
+          ABrtR2=1.0/sqrt(AB2);
+
+// piB is similary formulation to (a) Eq. 36 and (b) Eq. 18
+
+          piB[n]=(ABrtR1+ABrtR2)*pi_a[iij]*betaP_ij;
+          dPiB1=-.5*(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_c[iij]*pi_a[iij]*betaP_ij;
+          dPiB2=.25*BBrtR*(pow(ABrtR2,3)-pow(ABrtR1,3))*pi_c[iij]*pi_a[iij]*betaP_ij;
+          dPiB3=((ABrtR1+ABrtR2)*pi_a[iij]-(pow(ABrtR1,3)+pow(ABrtR2,3))*pi_a[iij]
+              *betaP_ij*betaP_ij)*dBetaP_ij/r_ij;
+          n++;
+          
+          pp2=2.0*betaP_ij;
+          for(m=0;m<nb_t;m++) {
+            bt_i=bt_pi[m].i;
+            bt_j=bt_pi[m].j;
+            xtmp[0]=x[bt_j][0]-x[bt_i][0];
+            xtmp[1]=x[bt_j][1]-x[bt_i][1];
+            xtmp[2]=x[bt_j][2]-x[bt_i][2];
+            for(pp=0;pp<3;pp++) { 
+              bt_pi[m].dPiB[pp]=
+                  +dPiB1*bt_pi[m].dAA[pp]
+                  +dPiB2*bt_pi[m].dBB[pp];
+              ftmp[pp]=pp2*bt_pi[m].dPiB[pp];
+              f[bt_i][pp]-=ftmp[pp];
+              f[bt_j][pp]+=ftmp[pp];
+            }
+            if(evflag) {
+              ev_tally_xyz(bt_i,bt_j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                  ,ftmp[2],xtmp[0],xtmp[1],xtmp[2]);
+            }
+          }
+          for(pp=0;pp<3;pp++) { 
+            ftmp[pp]=pp2*dPiB3*dis_ij[pp];
+            f[i][pp]-=ftmp[pp];
+            f[j][pp]+=ftmp[pp];
+          }
+          if(evflag) {
+            ev_tally_xyz(i,j,nlocal,newton_pair,0.0,0.0,ftmp[0],ftmp[1]
+                ,ftmp[2],dis_ij[0],dis_ij[1],dis_ij[2]);
+          }
+        }
+      }
+    }
+  }
+  destroy_pi();
+}
+ 
+ 
+/* ----------------------------------------------------------------------
+   read BOP potential file
+------------------------------------------------------------------------- */
+
+void PairBOP::read_file(char *filename)
+{
+  int i,j,k;
+  int ij,ii,jj;
+  int buf1;
+  int n;
+  double buf2;
+  char s[MAXLINE];
+  char buf[2];
+
+  MPI_Comm_rank(world,&me);
+  
+// read file on proc 0
+
+  rcore=0.1;
+
+  if (me == 0) {
+    FILE *fp = fopen(filename,"r");
+    if (fp == NULL) {
+      char str[128];
+      sprintf(str,"Cannot open BOP potential file %s\n",filename);
+      error->one(FLERR,str);
+    }
+
+// read parameters
+
+    fgets(s,MAXLINE,fp);
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%d",&bop_types);
+    fclose(fp);
+    npairs=bop_types*(bop_types+1)/2;
+  }
+  MPI_Bcast(&bop_types,1,MPI_INT,0,world);
+  MPI_Bcast(&npairs,1,MPI_INT,0,world);
+  allocate();
+  memory->create(pi_a,npairs,"BOP:pi_a");
+  memory->create(pro_delta,bop_types,"BOP:pro_delta");
+  memory->create(pi_delta,npairs,"BOP:pi_delta");
+  memory->create(pi_p,bop_types,"BOP:pi_p");
+  memory->create(pi_c,npairs,"BOP:pi_c");
+  memory->create(sigma_r0,npairs,"BOP:sigma_r0");
+  memory->create(pi_r0,npairs,"BOP:pi_r0");
+  memory->create(phi_r0,npairs,"BOP:phi_r0");
+  memory->create(sigma_rc,npairs,"BOP:sigma_rc");
+  memory->create(pi_rc,npairs,"BOP:pi_rc");
+  memory->create(phi_rc,npairs,"BOP:phi_rc");
+  memory->create(r1,npairs,"BOP:r1");
+  memory->create(sigma_beta0,npairs,"BOP:sigma_beta0");
+  memory->create(pi_beta0,npairs,"BOP:pi_beta0");
+  memory->create(phi0,npairs,"BOP:phi0");
+  memory->create(sigma_n,npairs,"BOP:sigma_n");
+  memory->create(pi_n,npairs,"BOP:pi_n");
+  memory->create(phi_m,npairs,"BOP:phi_m");
+  memory->create(sigma_nc,npairs,"BOP:sigma_nc");
+  memory->create(pi_nc,npairs,"BOP:pi_nc");
+  memory->create(phi_nc,npairs,"BOP:phi_nc");
+  memory->create(pro,bop_types,"BOP:pro");
+  memory->create(sigma_delta,npairs,"BOP:sigma_delta");
+  memory->create(sigma_c,npairs,"BOP:sigma_c");
+  memory->create(sigma_a,npairs,"BOP:sigma_a");
+  memory->create(sigma_g0,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g0");
+  memory->create(sigma_g1,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g1");
+  memory->create(sigma_g2,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g2");
+  memory->create(sigma_g3,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g3");
+  memory->create(sigma_g4,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g4");
+  memory->create(sigma_f,npairs,"BOP:sigma_f");
+  memory->create(sigma_k,npairs,"BOP:sigma_k");
+  memory->create(small3,npairs,"BOP:small3");
+
+  if (me == 0) {
+    words = new char*[bop_types];
+    for(i=0;i<bop_types;i++) words[i]=NULL;
+    FILE *fp = fopen(filename,"r");
+    if (fp == NULL) {
+      char str[128];
+      sprintf(str,"Cannot open BOP potential file %s\n",filename);
+      error->one(FLERR,str);
+    }
+    fgets(s,MAXLINE,fp);
+    fgets(s,MAXLINE,fp);
+    for(i=0;i<bop_types;i++) {
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%d %lf %s",&buf1,&buf2,buf);
+      n= strlen(buf)+1;
+      words[i] = new char[n];
+      strcpy(words[i],buf);
+    }
+    fgets(s,MAXLINE,fp);
+    fgets(s,MAXLINE,fp);
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%lf%lf%lf%lf%lf%lf%lf",&small1,&small2,&small3g,&small4
+        ,&small5,&small6,&small7);
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%d%lf%lf",&ncutoff,&rbig,&rsmall);
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%lf%lf%d",&which,&alpha,&nfunc);
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%lf%lf%lf",&alpha1,&beta1,&gamma1);
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%lf%lf",&alpha2,&beta2);
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%lf%lf",&alpha3,&beta3);
+    fgets(s,MAXLINE,fp);
+    fgets(s,MAXLINE,fp);
+    for(i=0;i<bop_types;i++) {
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf",&pro[i],&pro_delta[i],&pi_p[i]);
+    }
+    fgets(s,MAXLINE,fp);
+    fgets(s,MAXLINE,fp);
+    cutmax=0;
+    
+    for(i=0;i<bop_types;i++) {
+      ii=i+1;
+      for(j=i;j<bop_types;j++) {
+        jj=j+1;
+        if(ii==jj)
+          ij=ii-1;
+        else if(ii<jj)
+          ij=ii*bop_types-ii*(ii+1)/2+jj-1;
+        else
+          ij=jj*bop_types-jj*(jj+1)/2+ii-1;
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf%lf",&sigma_r0[ij],&sigma_rc[ij],&r1[ij],&rcut[ij]);
+        if(rcut[ij]>cutmax)
+          cutmax=rcut[ij];
+        pi_r0[ij]=sigma_r0[ij];
+        phi_r0[ij]=sigma_r0[ij];
+        pi_rc[ij]=sigma_rc[ij];
+        phi_rc[ij]=sigma_rc[ij];
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf",&phi_m[ij],&sigma_n[ij],&sigma_nc[ij]);
+        pi_n[ij]=sigma_n[ij];
+        pi_nc[ij]=sigma_nc[ij];
+        phi_nc[ij]=sigma_nc[ij];
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf",&phi0[ij],&sigma_beta0[ij],&pi_beta0[ij]);
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf",&sigma_a[ij],&sigma_c[ij],&sigma_delta[ij]);
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf",&pi_a[ij],&pi_c[ij],&pi_delta[ij]);
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf",&sigma_f[ij],&sigma_k[ij],&small3[ij]);
+      }
+    }
+    fgets(s,MAXLINE,fp);
+    fgets(s,MAXLINE,fp);
+    for(i=0;i<bop_types;i++) {
+      for(j=0;j<bop_types;j++) {
+        for(k=j;k<bop_types;k++) {
+          fgets(s,MAXLINE,fp);
+          sscanf(s,"%lf%lf%lf",&sigma_g0[j][i][k],&sigma_g1[j][i][k]
+              ,&sigma_g2[j][i][k]);
+          sigma_g0[k][i][j]=sigma_g0[j][i][k];
+          sigma_g1[k][i][j]=sigma_g1[j][i][k];
+          sigma_g2[k][i][j]=sigma_g2[j][i][k];
+        }
+      }
+    }
+    for(i=0;i<npairs;i++) {
+      dr[i]=rcut[i]/(nr-1.0);
+      rdr[i]=1.0/dr[i];
+    }
+    fclose(fp);
+  }
+  MPI_Bcast(&small1,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small2,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small3g,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small4,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small5,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small6,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small7,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&ncutoff,1,MPI_INT,0,world);
+  MPI_Bcast(&rbig,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&rsmall,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&which,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&alpha,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&nfunc,1,MPI_INT,0,world);
+  MPI_Bcast(&alpha1,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&beta1,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&gamma1,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&alpha2,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&beta2,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&alpha3,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&beta3,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pro[0],bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pro_delta[0],bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_p[0],bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_r0[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_rc[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&r1[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&rcut[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&cutmax,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_r0[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&phi_r0[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_rc[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&phi_rc[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&phi_m[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_n[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_nc[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_n[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_nc[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&phi_nc[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&phi0[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_beta0[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_beta0[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_a[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_c[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_delta[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_a[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_c[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_delta[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_f[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_k[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small3[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g0[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g1[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g2[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g3[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g4[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&dr[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&rdr[0],npairs,MPI_DOUBLE,0,world);
+}
+
+void PairBOP::read_table(char *filename)
+{
+  int i,j,k,n;
+  int buf1;
+  double buf2;
+  char s[MAXLINE],buf[2];
+
+  MPI_Comm_rank(world,&me);
+
+  if (me == 0) {
+    FILE *fp = fopen(filename,"r");
+    if (fp == NULL) {
+      char str[128];
+      sprintf(str,"Cannot open BOP potential file %s\n",filename);
+      error->one(FLERR,str);
+    }
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%d",&bop_types);
+    words = new char*[bop_types];
+    for(i=0;i<bop_types;i++) words[i]=NULL;
+    for(i=0;i<bop_types;i++) {
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%d %lf %s",&buf1,&buf2,buf);
+      n= strlen(buf)+1;
+      words[i] = new char[n];
+      strcpy(words[i],buf);
+    }
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%d %d",&nr,&nBOt);
+    fclose(fp);
+    npairs=bop_types*(bop_types+1)/2;
+  }
+
+  MPI_Bcast(&nr,1,MPI_INT,0,world);
+  MPI_Bcast(&nBOt,1,MPI_INT,0,world);
+  MPI_Bcast(&bop_types,1,MPI_INT,0,world);
+  MPI_Bcast(&npairs,1,MPI_INT,0,world);
+  memory->create(pi_a,npairs,"BOP:pi_a");
+  memory->create(pro_delta,bop_types,"BOP:pro_delta");
+  memory->create(pi_delta,npairs,"BOP:pi_delta");
+  memory->create(pi_p,bop_types,"BOP:pi_p");
+  memory->create(pi_c,npairs,"BOP:pi_c");
+  memory->create(r1,npairs,"BOP:r1");
+  memory->create(pro,bop_types,"BOP:pro");
+  memory->create(sigma_delta,npairs,"BOP:sigma_delta");
+  memory->create(sigma_c,npairs,"BOP:sigma_c");
+  memory->create(sigma_a,npairs,"BOP:sigma_a");
+  memory->create(sigma_g0,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g0");
+  memory->create(sigma_g1,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g1");
+  memory->create(sigma_g2,bop_types
+      ,bop_types,bop_types,"BOP:sigma_g2");
+  memory->create(sigma_f,npairs,"BOP:sigma_f");
+  memory->create(sigma_k,npairs,"BOP:sigma_k");
+  memory->create(small3,npairs,"BOP:small3");
+  allocate();
+
+  if (me == 0) {
+    FILE *fp = fopen(filename,"r");
+    if (fp == NULL) {
+      char str[128];
+      sprintf(str,"Cannot open BOP potential file %s\n",filename);
+      error->one(FLERR,str);
+    }
+    for(i=0;i<bop_types+2;i++) {
+      fgets(s,MAXLINE,fp);
+    }
+    fgets(s,MAXLINE,fp);
+    sscanf(s,"%lf%lf%lf%lf%lf%lf%lf",&small1,&small2,&small3g
+        ,&small4,&small5,&small6,&small7);
+    for(i=0;i<bop_types;i++) {
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%lf",&pi_p[i]);
+    }
+    cutmax=0;
+    for(i=0;i<npairs;i++) {
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%lf",&rcut[i]);
+      if(rcut[i]>cutmax)
+        cutmax=rcut[i];
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%lf%lf%lf%lf",&sigma_c[i],&sigma_a[i],&pi_c[i],&pi_a[i]);
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%lf%lf",&sigma_delta[i],&pi_delta[i]);
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%lf%lf%lf",&sigma_f[i],&sigma_k[i],&small3[i]);
+    }    
+    for(i=0;i<bop_types;i++) 
+      for(j=0;j<bop_types;j++)
+        for(k=0;k<bop_types;k++) {
+          fgets(s,MAXLINE,fp);
+          sscanf(s,"%lf%lf%lf",&sigma_g0[i][j][k],&sigma_g1[i][j][k],&sigma_g2[i][j][k]);
+        }
+    for(i=0;i<npairs;i++) {
+      for(j=0;j<nr;j++) { 
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf%lf%lf",&pRepul[i][j],&pRepul[i][j+1]
+            ,&pRepul[i][j+2],&pRepul[i][j+3],&pRepul[i][j+4]);
+        j+=4;
+      }
+    }
+    for(i=0;i<npairs;i++) {
+      for(j=0;j<nr;j++) { 
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf%lf%lf",&pBetaS[i][j],&pBetaS[i][j+1]
+            ,&pBetaS[i][j+2],&pBetaS[i][j+3],&pBetaS[i][j+4]);
+        j+=4;
+      }
+    }
+    for(i=0;i<npairs;i++) {
+      for(j=0;j<nr;j++) { 
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf%lf%lf",&pBetaP[i][j],&pBetaP[i][j+1]
+            ,&pBetaP[i][j+2],&pBetaP[i][j+3],&pBetaP[i][j+4]);
+        j+=4;
+      }
+    }
+    for(i=0;i<npairs;i++) {
+      for(j=0;j<nBOt;j++) { 
+        fgets(s,MAXLINE,fp);
+        sscanf(s,"%lf%lf%lf%lf%lf",&FsigBO[i][j],&FsigBO[i][j+1]
+            ,&FsigBO[i][j+2],&FsigBO[i][j+3],&FsigBO[i][j+4]);
+        j+=4;
+      }
+    }
+    for(i=0;i<bop_types;i++) {
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%lf",&pro_delta[i]);
+    }
+    for(i=0;i<bop_types;i++) {
+      fgets(s,MAXLINE,fp);
+      sscanf(s,"%lf",&pro[i]);
+    }
+    for(i=0;i<npairs;i++) {
+      dr[i]=rcut[i]/((double)nr-1.0); 
+      rdr[i]=1.0/dr[i];
+    }
+    dBO=1.0/((double)nBOt-1.0);
+    rdBO=1.0/(double)dBO;
+
+    for(i=0;i<npairs;i++) {
+      pBetaS1[i][0]=pBetaS[i][1]-pBetaS[i][0];
+      pBetaS1[i][1]=0.5*(pBetaS[i][2]-pBetaS[i][0]);
+      pBetaS1[i][nr-2]=0.5*(pBetaS[i][nr-1]-pBetaS[i][nr-3]);
+      pBetaS1[i][nr-1]=pBetaS[i][nr-1]-pBetaS[i][nr-2];
+      pBetaP1[i][0]=pBetaP[i][1]-pBetaP[i][0];
+      pBetaP1[i][1]=0.5*(pBetaP[i][2]-pBetaP[i][0]);
+      pBetaP1[i][nr-2]=0.5*(pBetaP[i][nr-1]-pBetaP[i][nr-3]);
+      pBetaP1[i][nr-1]=pBetaP[i][nr-1]-pBetaP[i][nr-2];
+      pRepul1[i][0]=pRepul[i][1]-pRepul[i][0];
+      pRepul1[i][1]=0.5*(pRepul[i][2]-pRepul[i][0]);
+      pRepul1[i][nr-2]=0.5*(pRepul[i][nr-1]-pRepul[i][nr-3]);
+      pRepul1[i][nr-1]=pRepul[i][nr-1]-pRepul[i][nr-2];
+      FsigBO1[i][0]=FsigBO[i][1]-FsigBO[i][0];
+      FsigBO1[i][1]=0.5*(FsigBO[i][2]-FsigBO[i][0]);
+      FsigBO1[i][nBOt-2]=0.5*(FsigBO[i][nBOt-1]-FsigBO[i][nBOt-3]);
+      FsigBO1[i][nBOt-1]=FsigBO[i][nBOt-1]-FsigBO[i][nBOt-2];
+      for(k=2;k<nr-2;k++) {
+        pBetaS1[i][k]=((pBetaS[i][k-2]-pBetaS[i][k+2])
+            +8.0*(pBetaS[i][k+1]-pBetaS[i][k-1]))/12.0;
+        pBetaP1[i][k]=((pBetaP[i][k-2]-pBetaP[i][k+2])
+            +8.0*(pBetaP[i][k+1]-pBetaP[i][k-1]))/12.0;
+        pRepul1[i][k]=((pRepul[i][k-2]-pRepul[i][k+2])
+            +8.0*(pRepul[i][k+1]-pRepul[i][k-1]))/12.0;
+      }
+      for(k=2;k<nr-2;k++) {
+        FsigBO1[i][k]=((FsigBO[i][k-2]-FsigBO[i][k+2])
+            +8.0*(FsigBO[i][k+1]-FsigBO[i][k-1]))/12.0;
+      }
+      for(k=0;k<nr-1;k++) {
+        pBetaS2[i][k]=3.0*(pBetaS[i][k+1]-pBetaS[i][k])
+            -2.0*pBetaS1[i][k]-pBetaS1[i][k+1];
+        pBetaS3[i][k]=pBetaS1[i][k]+pBetaS1[i][k+1]
+            -2.0*(pBetaS[i][k+1]-pBetaS[i][k]);
+        pBetaP2[i][k]=3.0*(pBetaP[i][k+1]-pBetaP[i][k])
+            -2.0*pBetaP1[i][k]-pBetaP1[i][k+1];
+        pBetaP3[i][k]=pBetaP1[i][k]+pBetaP1[i][k+1]
+            -2.0*(pBetaP[i][k+1]-pBetaP[i][k]);
+        pRepul2[i][k]=3.0*(pRepul[i][k+1]-pRepul[i][k])
+            -2.0*pRepul1[i][k]-pRepul1[i][k+1];
+        pRepul3[i][k]=pRepul1[i][k]+pRepul1[i][k+1]
+            -2.0*(pRepul[i][k+1]-pRepul[i][k]);
+      }
+      for(k=0;k<nBOt-1;k++) {
+        FsigBO2[i][k]=3.0*(FsigBO[i][k+1]-FsigBO[i][k])
+            -2.0*FsigBO1[i][k]-FsigBO1[i][k+1];
+        FsigBO3[i][k]=FsigBO1[i][k]+FsigBO1[i][k+1]
+            -2.0*(FsigBO[i][k+1]-FsigBO[i][k]);
+      }
+      pBetaS2[i][nr-1]=0.0;
+      pBetaS3[i][nr-1]=0.0;
+      pBetaP2[i][nr-1]=0.0;
+      pBetaP3[i][nr-1]=0.0;
+      pRepul2[i][nr-1]=0.0;
+      pRepul3[i][nr-1]=0.0;
+      FsigBO2[i][nBOt-1]=0.0;
+      FsigBO3[i][nBOt-1]=0.0;
+      for(k=0;k<nr;k++) {
+        pBetaS4[i][k]=pBetaS1[i][k]/dr[i];
+        pBetaS5[i][k]=2.0*pBetaS2[i][k]/dr[i];
+        pBetaS6[i][k]=3.0*pBetaS3[i][k]/dr[i];
+        pBetaP4[i][k]=pBetaP1[i][k]/dr[i];
+        pBetaP5[i][k]=2.0*pBetaP2[i][k]/dr[i];
+        pBetaP6[i][k]=3.0*pBetaP3[i][k]/dr[i];
+        pRepul4[i][k]=pRepul1[i][k]/dr[i];
+        pRepul5[i][k]=2.0*pRepul2[i][k]/dr[i];
+        pRepul6[i][k]=3.0*pRepul3[i][k]/dr[i];
+      }
+      for(k=0;k<nBOt;k++) {
+        FsigBO4[i][k]=FsigBO1[i][k]/dBO;
+        FsigBO5[i][k]=2.0*FsigBO2[i][k]/dBO;
+        FsigBO6[i][k]=3.0*FsigBO3[i][k]/dBO;
+      }
+    }
+    fclose(fp);
+  }
+  MPI_Bcast(&rdBO,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&dBO,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&bop_types,1,MPI_INT,0,world);
+  MPI_Bcast(&small1,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small2,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small3g,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small4,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small5,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small6,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small7,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pro[0],bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pro_delta[0],bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_p[0],bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&r1[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&rcut[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&cutmax,1,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_a[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_c[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_delta[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_a[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_c[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pi_delta[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_f[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_k[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&small3[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g0[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g1[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&sigma_g2[0][0][0],bop_types*bop_types*bop_types,MPI_DOUBLE,0,world);
+  MPI_Bcast(&dr[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&rdr[0],npairs,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaS[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaS1[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaS2[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaS3[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaS4[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaS5[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaS6[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaP[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaP1[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaP2[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaP3[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaP4[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaP5[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pBetaP6[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pRepul[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pRepul1[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pRepul2[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pRepul3[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pRepul4[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pRepul5[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&pRepul6[0][0],npairs*nr,MPI_DOUBLE,0,world);
+  MPI_Bcast(&FsigBO[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+  MPI_Bcast(&FsigBO1[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+  MPI_Bcast(&FsigBO2[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+  MPI_Bcast(&FsigBO3[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+  MPI_Bcast(&FsigBO4[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+  MPI_Bcast(&FsigBO5[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+  MPI_Bcast(&FsigBO6[0][0],npairs*nBOt,MPI_DOUBLE,0,world);
+}
+
+void PairBOP::setPbetaS()
+{
+  int i,j,k;
+  double r,value,dvalue;
+ 
+  for(i=0;i<npairs;i++) {
+    for(j=0;j<nr;j++) {
+      r=(double)j*dr[i];
+      if(r<rcore)
+        r=rcore;
+      if(ncutoff==3) {
+        if(r>=rcut[i])
+          pBetaS[i][j]=0.0;
+        else if(r<=r1[i]) {
+          value=betaSfunc(i,r);
+          dvalue=dBetaSfunc(i,r,value,1.0);
+          pBetaS[i][j]=value;
+        }
+        else {
+          value=betaSfunc(i,r1[i]);
+          dvalue=dBetaSfunc(i,r1[i],value,1.0);
+          pBetaS[i][j]=-(r-rcut[i])*(r-rcut[i])*(value*(2.0*r-3.0*r1[i]+rcut[i])
+              -dvalue*(r-r1[i])*(r1[i]-rcut[i]))/((r1[i]-rcut[i])
+              *(r1[i]-rcut[i])*(r1[i]-rcut[i]));
+        }
+      }
+      else {
+        if(r>=rcut[i])
+          pBetaS[i][j]=0.0;
+        else {
+          value=betaSfunc(i,r);
+          dvalue=dBetaSfunc(i,r,value,0.0);
+          pBetaS[i][j]=value*cutoff(r1[i],rcut[i],ncutoff,r);
+        }
+      }
+    }
+    pBetaS[i][nr-1]=0.0;
+    pBetaS1[i][0]=pBetaS[i][1]-pBetaS[i][0];
+    pBetaS1[i][1]=0.5*(pBetaS[i][2]-pBetaS[i][0]);
+    pBetaS1[i][nr-2]=0.5*(pBetaS[i][nr-1]-pBetaS[i][nr-3]);
+    pBetaS1[i][nr-1]=pBetaS[i][nr-1]-pBetaS[i][nr-2];
+     
+    for(k=2;k<nr-2;k++) {
+      pBetaS1[i][k]=((pBetaS[i][k-2]-pBetaS[i][k+2])+8.0*(pBetaS[i][k+1]
+          -pBetaS[i][k-1]))/12.0;
+    }
+    for(k=0;k<nr-1;k++) {
+      pBetaS2[i][k]=3.0*(pBetaS[i][k+1]-pBetaS[i][k])-2.0*pBetaS1[i][k]-pBetaS1[i][k+1];
+      pBetaS3[i][k]=pBetaS1[i][k]+pBetaS1[i][k+1]-2.0*(pBetaS[i][k+1]-pBetaS[i][k]);
+    }
+    pBetaS2[i][nr-1]=0.0;
+    pBetaS3[i][nr-1]=0.0;
+    for(k=0;k<nr;k++) {
+      pBetaS4[i][k]=pBetaS1[i][k]/dr[i];
+      pBetaS5[i][k]=2.0*pBetaS2[i][k]/dr[i];
+      pBetaS6[i][k]=3.0*pBetaS3[i][k]/dr[i];
+    }
+  }
+}
+
+void PairBOP::setPbetaP()
+{
+  int i,j,k;
+  double r,value,dvalue;
+
+  for(i=0;i<npairs;i++) {
+    for(j=0;j<nr;j++) {
+      r=(double)j*dr[i];
+      if(r<rcore)
+        r=rcore;
+      if(ncutoff==3) {
+        if(r>=rcut[i])
+          pBetaP[i][j]=0.0;
+        else if(r<=r1[i]) {
+          value=betaPfunc(i,r);
+          dvalue=dBetaPfunc(i,r,value,0.0);
+          pBetaP[i][j]=value;
+        }
+        else {
+          value=betaPfunc(i,r1[i]);
+          dvalue=dBetaPfunc(i,r1[i],value,1.0);
+          pBetaP[i][j]=-(r-rcut[i])*(r-rcut[i])*(value*(2.0*r-3.0*r1[i]
+              +rcut[i])-dvalue*(r-r1[1])*(r1[i]-rcut[i]))/((r1[i]-rcut[i])
+              *(r1[i]-rcut[i])*(r1[i]-rcut[i]));
+        }
+      }
+      else {
+        if(r>=rcut[i])
+          pBetaP[i][j]=0.0;
+        else {
+          value=betaPfunc(i,r);
+          dvalue=dBetaPfunc(i,r,value,0.0);
+          pBetaP[i][j]=value*cutoff(r1[i],rcut[i],ncutoff,r);
+        }
+      }
+    }
+    pBetaP[i][nr-1]=0.0;
+    pBetaP1[i][0]=pBetaP[i][1]-pBetaP[i][0];
+    pBetaP1[i][1]=0.5*(pBetaP[i][2]-pBetaP[i][0]);
+    pBetaP1[i][nr-2]=0.5*(pBetaP[i][nr-1]-pBetaP[i][nr-3]);
+    pBetaP1[i][nr-1]=pBetaP[i][nr-1]-pBetaP[i][nr-2];
+    for(k=2;k<nr-2;k++) 
+      pBetaP1[i][k]=((pBetaP[i][k-2]-pBetaP[i][k+2])+8.0*(pBetaP[i][k+1]
+          -pBetaP[i][k-1]))/12.0;
+    for(k=0;k<nr-1;k++) {
+      pBetaP2[i][k]=3.0*(pBetaP[i][k+1]-pBetaP[i][k])-2.0*pBetaP1[i][k]-pBetaP1[i][k+1];
+      pBetaP3[i][k]=pBetaP1[i][k]+pBetaP1[i][k+1]-2.0*(pBetaP[i][k+1]-pBetaP[i][k]);
+    }
+    pBetaP2[i][nr-1]=0.0;
+    pBetaP3[i][nr-1]=0.0;
+    for(k=0;k<nr;k++) {
+      pBetaP4[i][k]=pBetaP1[i][k]/dr[i];
+      pBetaP5[i][k]=2.0*pBetaP2[i][k]/dr[i];
+      pBetaP6[i][k]=3.0*pBetaP3[i][k]/dr[i];
+    }
+  }
+}
+
+void PairBOP::setPrepul()
+{
+  int i,j,k;
+  double r,value,dvalue;
+ 
+  for(i=0;i<npairs;i++) {
+    for(j=0;j<nr;j++) {
+      r=(double)j*dr[i];
+      if(r<rcore)
+        r=rcore;
+      if(ncutoff==3) {
+        if(r>=rcut[i])
+          pRepul[i][j]=0.0;
+        else if(r<=r1[i]) {
+          value=repulfunc(i,r);
+          dvalue=dRepulfunc(i,r,value,0.0);
+          pRepul[i][j]=value;
+        }
+        else {
+          value=repulfunc(i,r1[i]);
+          dvalue=dRepulfunc(i,r1[i],value,1.0);
+          pRepul[i][j]=-(r-rcut[i])*(r-rcut[i])*(value*(2.0*r-3.0*r1[i]+rcut[i])
+              -dvalue*(r-r1[i])*(r1[i]-rcut[i]))/((r1[i]-rcut[i])
+              *(r1[i]-rcut[i])*(r1[i]-rcut[i]));
+        }
+      }
+      else {
+        if(r>=rcut[i])
+          pRepul[i][j]=0.0;
+        else {
+          value=repulfunc(i,r);
+          dvalue=dRepulfunc(i,r,value,0.0);
+          pRepul[i][j]=value*cutoff(r1[i],rcut[i],ncutoff,r);
+        }
+      }
+    }
+    pRepul[i][nr-1]=0.0;
+    pRepul1[i][0]=pRepul[i][1]-pRepul[i][0];
+    pRepul1[i][1]=0.5*(pRepul[i][2]-pRepul[i][0]);
+    pRepul1[i][nr-2]=0.5*(pRepul[i][nr-1]-pRepul[i][nr-3]);
+    pRepul1[i][nr-1]=pRepul[i][nr-1]-pRepul[i][nr-2];
+    for(k=2;k<nr-2;k++)
+      pRepul1[i][k]=((pRepul[i][k-2]-pRepul[i][k+2])+8.0*(pRepul[i][k+1]
+          -pRepul[i][k-1]))/12.0;
+    for(k=0;k<nr-1;k++) {
+      pRepul2[i][k]=3.0*(pRepul[i][k+1]-pRepul[i][k])-2.0*pRepul1[i][k]-pRepul1[i][k+1];
+      pRepul3[i][k]=pRepul1[i][k]+pRepul1[i][k+1]-2.0*(pRepul[i][k+1]-pRepul[i][k]);
+    }
+    pRepul2[i][nr-1]=0.0;
+    pRepul3[i][nr-1]=0.0;
+    for(k=0;k<nr;k++) {
+      pRepul4[i][k]=pRepul1[i][k]/dr[i];
+      pRepul5[i][k]=2.0*pRepul2[i][k]/dr[i];
+      pRepul6[i][k]=3.0*pRepul3[i][k]/dr[i];
+    }
+  }
+}
+
+double PairBOP::betaSfunc(int i,double r)
+{
+  double temp_value;
+
+  if(nfunc==1) {
+    temp_value=pow(sigma_r0[i]/r,sigma_n[i])*exp(sigma_n[i]*pow(sigma_r0[i]
+        /sigma_rc[i],sigma_nc[i])-sigma_n[i]*pow(r/sigma_rc[i],sigma_nc[i]));
+    temp_value=sigma_beta0[i]*temp_value;
+  }
+  if(nfunc==2)
+    temp_value=sigma_beta0[i]*exp(-sigma_n[i]*r);
+  if(nfunc==3)
+    temp_value=sigma_beta0[i]/pow(r,sigma_n[i]);
+  return(temp_value);
+}
+
+double PairBOP::dBetaSfunc(int i,double r,double value,double dmore)
+{
+  double temp_dvalue;
+  
+  if(nfunc==1)
+    if(dmore==1.0)
+      temp_dvalue=-sigma_n[i]*value/r*(1.0+sigma_nc[i]
+          *pow(r/sigma_rc[i],sigma_nc[i]));
+  if(nfunc==2)
+    if(dmore==1.0)
+      temp_dvalue=-sigma_n[i]*value;
+  if(nfunc==3)
+    if(dmore==1.0)
+      temp_dvalue=-sigma_n[i]*value/r;
+  return(temp_dvalue);
+}
+
+
+double PairBOP::betaPfunc(int i,double r)
+{
+  double temp_value;
+
+  if(nfunc==1) {
+    temp_value=pow(pi_r0[i]/r,pi_n[i])*exp(pi_n[i]*pow(pi_r0[i]
+        /pi_rc[i],pi_nc[i])-pi_n[i]*pow(r/pi_rc[i],pi_nc[i]));
+        temp_value=pi_beta0[i]*temp_value;
+  }
+  if(nfunc==2)
+    temp_value=pi_beta0[i]*exp(-pi_n[i]*r);
+  if(nfunc==3)
+    temp_value=pi_beta0[i]/pow(r,pi_n[i]);
+  return(temp_value);
+}
+
+double PairBOP::dBetaPfunc(int i,double r,double value,double dmore)
+{
+  double temp_dvalue;
+
+  if(nfunc==1)
+    if(dmore==1.0)
+      temp_dvalue=-pi_n[i]*value/r*(1.0+pi_nc[i]*pow(r/pi_rc[i],pi_nc[i]));
+  if(nfunc==2)
+    if(dmore==1.0) 
+      temp_dvalue=-pi_n[i]*value;
+  if(nfunc==3)
+    if(dmore==1.0)
+      temp_dvalue=-pi_n[i]*value/r;
+  return(temp_dvalue);
+}
+
+double PairBOP::repulfunc(int i,double r)
+{
+  double temp_value;
+
+  if(nfunc==1) {
+    temp_value=pow(phi_r0[i]/r,phi_m[i])*exp(phi_m[i]*pow(phi_r0[i]/phi_rc[i]
+        ,phi_nc[i])-phi_m[i]*pow(r/phi_rc[i],phi_nc[i]));
+    temp_value=phi0[i]*temp_value;
+  }
+  if(nfunc==2)
+    temp_value=phi0[i]*exp(-phi_m[i]*r);
+  if(nfunc==3)
+    temp_value=phi0[i]/pow(r,phi_m[i]);
+  return(temp_value);
+} 
+
+double PairBOP::dRepulfunc(int i,double r,double value,double dmore)
+{
+  double temp_dvalue;
+
+  if(nfunc==1)
+    if(dmore==1.0)
+      temp_dvalue=-phi_m[i]*value/r*(1.0+phi_nc[i]*pow(r/phi_rc[i],phi_nc[i]));
+  if(nfunc==2)
+    if(dmore==1.0)
+      temp_dvalue=-phi_m[i]*value;
+  if(nfunc==3)
+    if(dmore==1.0)
+      temp_dvalue=-phi_m[i]*value/r;
+  return(temp_dvalue);
+} 
+
+void PairBOP::setSign()
+{
+  int i,j,k;
+  double y0,tmp,xBO,fth,cs,bigF;
+  double epsilon,fsigma1,slope,sat;
+  
+  dBO=1.0/(nBOt-1.0);
+  rdBO=1.0/dBO;
+  for(i=0;i<npairs;i++) {
+    for(j=0;j<nBOt;j++) {
+      xBO=(double)j*dBO;
+      if(which==1.0) {
+        fth=0.0;
+        if(xBO>alpha)
+          fth=4.0/3.0*(xBO-alpha);
+        if(sigma_f[i]<=fth)
+          FsigBO[i][j]=2.0*sigma_f[i];
+        else if(sigma_f[i]>=1.0-fth)
+          FsigBO[i][j]=2.0*(1.0-sigma_f[i]);
+        else {
+          cs=0.0;
+          if(xBO<alpha)
+            cs=32.0*(alpha-xBO);
+          bigF=(sigma_f[i]*(1.0-sigma_f[i])-fth*(1.0-fth))/pow(1.0-2.0*fth,2);
+          FsigBO[i][j]=2.0*fth+2.0*bigF*(1.0-2.0*fth)*(1.0+bigF*(1.0-cs*bigF));
+        }
+      }
+      else if(which==2.0) {
+        epsilon=0.0000000001;
+        fsigma1=sigma_f[i];
+        if(fsigma1>0.5)
+          fsigma1=1.0-fsigma1;
+        y0=alpha1*pow(fsigma1,beta1)*pow(0.5-fsigma1,gamma1);
+        slope=(1.0-exp(-alpha2*pow(fsigma1,beta2)))/(1.0-exp(-alpha2*pow(0.5,beta2)));
+        sat=alpha3*fsigma1+beta3;
+        tmp=y0+slope*xBO+sat;
+        FsigBO[i][j]=(tmp-sqrt(tmp*tmp-4.0*(-epsilon*sqrt(1.0+slope*slope)
+            +y0*sat+slope*sat*xBO)))/2.0;
+      }
+    }
+    FsigBO1[i][0]=FsigBO[i][1]-FsigBO[i][0];
+    FsigBO1[i][1]=0.5*(FsigBO[i][2]-FsigBO[i][0]);
+    FsigBO1[i][nBOt-2]=0.5*(FsigBO[i][nBOt-1]-FsigBO[i][nBOt-3]);
+    FsigBO1[i][nBOt-1]=FsigBO[i][nBOt-1]-FsigBO[i][nBOt-2];
+    for(k=2;k<nBOt-2;k++)
+      FsigBO1[i][k]=((FsigBO[i][k-2]-FsigBO[i][k+2])+8.0*(FsigBO[i][k+1]
+          -FsigBO[i][k-1]))/12.0;
+    for(k=0;k<nBOt-1;k++) {
+      FsigBO2[i][k]=3.0*(FsigBO[i][k+1]-FsigBO[i][k])-2.0*FsigBO1[i][k]-FsigBO1[i][k+1];
+      FsigBO3[i][k]=FsigBO1[i][k]+FsigBO1[i][k+1]-2.0*(FsigBO[i][k+1]-FsigBO[i][k]);
+    }
+    FsigBO2[i][nBOt-1]=0.0;
+    FsigBO3[i][nBOt-1]=0.0;
+    for(k=0;k<nBOt;k++) {
+      FsigBO4[i][k]=FsigBO1[i][k]/dBO;
+      FsigBO5[i][k]=2.0*FsigBO2[i][k]/dBO;
+      FsigBO6[i][k]=3.0*FsigBO3[i][k]/dBO;
+    }
+  }
+}
+
+double PairBOP::cutoff(double rp,double vrcut,int mode,double r)
+{
+  double tmp,tmp_beta,tmp_alpha,cut_store;
+  
+  if(mode==1) {
+    tmp=(rsmall-rbig)*(r-rp)/(vrcut-rp)+rbig;
+    cut_store=(erfc(tmp)-erfc(rsmall))/(erfc(rbig)-erfc(rsmall));
+  }
+  else {
+    tmp_beta=log(log(rbig)/log(rsmall))/log(rp/vrcut);
+    tmp_alpha=-log(rbig)/pow(rp,tmp_beta);
+    cut_store=(exp(-tmp_alpha*pow(r,tmp_beta))-exp(-tmp_alpha*pow(vrcut
+        ,tmp_beta)))/(exp(-tmp_alpha*pow(rp,tmp_beta))-exp(-tmp_alpha
+        *pow(vrcut,tmp_beta)));
+  }
+  return(cut_store);
+}
+
+
+/* ----------------------------------------------------------------------
+   memory usage of local atom-based arrays 
+------------------------------------------------------------------------- */
+
+double PairBOP::memory_usage()
+{
+  int nlocal,nghost,nall;
+  int n = atom->ntypes; 
+  nlocal = atom->nlocal;
+  nghost = atom->nghost;
+  nall = nlocal + nghost;
+  double bytes = 0.0;
+
+// rcut
+  bytes += npairs * sizeof (double);
+// dr
+  bytes += npairs * sizeof (double);
+// rdr
+  bytes += npairs * sizeof (double);
+// setflag
+  bytes += (n+1) * (n+1) * sizeof (int);
+// cutsq
+  bytes += (n+1) * (n+1) * sizeof (double);
+// cutghost
+  bytes += (n+1) * (n+1) * sizeof (double);
+// cutghost
+  bytes += (n+1) * (n+1) * sizeof (double);
+// pBetaS
+  bytes += npairs * nr * sizeof (double);
+// pBetaS1
+  bytes += npairs * nr * sizeof (double);
+// pBetaS2
+  bytes += npairs * nr * sizeof (double);
+// pBetaS3
+  bytes += npairs * nr * sizeof (double);
+// pBetaS4
+  bytes += npairs * nr * sizeof (double);
+// pBetaS5
+  bytes += npairs * nr * sizeof (double);
+// pBetaS6
+  bytes += npairs * nr * sizeof (double);
+// pBetaP
+  bytes += npairs * nr * sizeof (double);
+// pBetaP1
+  bytes += npairs * nr * sizeof (double);
+// pBetaP2
+  bytes += npairs * nr * sizeof (double);
+// pBetaP3
+  bytes += npairs * nr * sizeof (double);
+// pBetaP4
+  bytes += npairs * nr * sizeof (double);
+// pBetaP5
+  bytes += npairs * nr * sizeof (double);
+// pBetaP6
+  bytes += npairs * nr * sizeof (double);
+// pRepul
+  bytes += npairs * nr * sizeof (double);
+// pRepul1
+  bytes += npairs * nr * sizeof (double);
+// pRepul2
+  bytes += npairs * nr * sizeof (double);
+// pRepul3
+  bytes += npairs * nr * sizeof (double);
+// pRepul4
+  bytes += npairs * nr * sizeof (double);
+// pRepul5
+  bytes += npairs * nr * sizeof (double);
+// pRepul6
+  bytes += npairs * nr * sizeof (double);
+// FsigBO
+  bytes += npairs * nr * sizeof (double);
+// FsigBO1
+  bytes += npairs * nr * sizeof (double);
+// FsigBO2
+  bytes += npairs * nr * sizeof (double);
+// FsigBO3
+  bytes += npairs * nr * sizeof (double);
+// FsigBO4
+  bytes += npairs * nr * sizeof (double);
+// FsigBO5
+  bytes += npairs * nr * sizeof (double);
+// FsigBO6
+  bytes += npairs * nr * sizeof (double);
+// itypeSigBk
+  bytes += neigh_total *neigh_ct* sizeof(int);
+// nSigBk
+  bytes += neigh_total * sizeof(int);
+// sigB
+  bytes += neigh_total * sizeof(int);
+// sigB1
+  bytes += neigh_total * sizeof(int);
+// nPiBk
+  bytes += neigh_total * sizeof(int);
+// piB
+  bytes += neigh_total * sizeof(int);
+// itypePiBk
+  bytes += neigh_total *neigh_ct* sizeof(int);
+// BOP_index
+    bytes += nall * sizeof(double);
+  if(otfly==0) {
+// cosAng
+    bytes += cos_total* sizeof(double);
+// dcAng
+    bytes += cos_total * 3 * 2 * sizeof(double);
+// disij
+    bytes += neigh_total * 3 * sizeof(double);
+// rij
+    bytes += neigh_total * sizeof(double);
+// betaS
+    bytes += neigh_total * sizeof(double);
+// dBetaS
+    bytes += neigh_total * sizeof(double);
+// betaP
+    bytes += neigh_total * sizeof(double);
+// dBetaP
+    bytes += neigh_total * sizeof(double);
+// repul
+    bytes += neigh_total * sizeof(double);
+// dRepul
+    bytes += neigh_total * sizeof(double);
+// cos_index
+    bytes += nall * sizeof(double);
+  }    
+// pi_a
+  bytes += npairs * sizeof(double);
+// pro_delta
+  bytes += npairs * sizeof(double);
+// pi_delta
+  bytes += npairs * sizeof(double);
+// pi_p
+  bytes += npairs * sizeof(double);
+// pi_c
+  bytes += npairs * sizeof(double);
+// sigma_r0
+  bytes += npairs * sizeof(double);
+// pi_r0
+  bytes += npairs * sizeof(double);
+// phi_r0
+  bytes += npairs * sizeof(double);
+// sigma_rc
+  bytes += npairs * sizeof(double);
+// pi_rc
+  bytes += npairs * sizeof(double);
+// pi_a
+  bytes += npairs * sizeof(double);
+// pro_delta
+  bytes += npairs * sizeof(double);
+// pi_delta
+  bytes += npairs * sizeof(double);
+// pi_p
+  bytes += npairs * sizeof(double);
+// pi_c
+  bytes += npairs * sizeof(double);
+// sigma_r0
+  bytes += npairs * sizeof(double);
+// pi_r0
+  bytes += npairs * sizeof(double);
+// phi_r0
+  bytes += npairs * sizeof(double);
+// sigma_rc
+  bytes += npairs * sizeof(double);
+// pi_rc
+  bytes += npairs * sizeof(double);
+// phi_rc
+  bytes += npairs * sizeof(double);
+// r1
+  bytes += npairs * sizeof(double);
+// sigma_beta0 
+  bytes += npairs * sizeof(double);
+// pi_beta0 
+  bytes += npairs * sizeof(double);
+// phi0
+  bytes += npairs * sizeof(double);
+// sigma_n
+  bytes += npairs * sizeof(double);
+// pi_n
+  bytes += npairs * sizeof(double);
+// phi_m
+  bytes += npairs * sizeof(double);
+// sigma_nc
+  bytes += npairs * sizeof(double);
+// pi_nc
+  bytes += npairs * sizeof(double);
+// phi_nc
+  bytes += npairs * sizeof(double);
+// pro
+  bytes += npairs * sizeof(double);
+// sigma_delta
+  bytes += npairs * sizeof(double);
+// sigma_c
+  bytes += npairs * sizeof(double);
+// sigma_a
+  bytes += npairs * sizeof(double);
+// sigma_g0
+  bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g1
+  bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g2
+  bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g3
+  bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_g4
+  bytes += bop_types * bop_types *bop_types * sizeof(double);
+// sigma_f
+  bytes += npairs * sizeof(double);
+// sigma_k
+  bytes += npairs * sizeof(double);
+// small3
+  bytes += npairs * sizeof(double);
+// bt_pi
+  bytes += maxneigh*(maxneigh/2) *sizeof(B_PI);
+// bt_sigma
+  bytes += maxneigh*(maxneigh/2) *sizeof(B_SG);
+
+  return bytes;
+}
+
+void PairBOP::memory_theta_create()
+{
+  int nlocal,nghost,nall;
+ 
+  nlocal = atom->nlocal;
+  nghost = atom->nghost;
+  nall = nlocal + nghost;
+  if(maxneigh<8) 
+    neigh_ct=(maxneigh-1)*(maxneigh-1)*(maxneigh-1);
+  else
+    neigh_ct=(maxneigh-1)*(maxneigh-1);
+  memory->create(itypeSigBk,neigh_total
+      ,neigh_ct,"itypeSigBk");
+  memory->create(nSigBk,neigh_total,"nSigBk");
+  memory->create(sigB,neigh_total,"sigB");
+  memory->create(sigB1,neigh_total,"sigB1");
+  memory->create(itypePiBk,neigh_total
+      ,neigh_ct,"itypePiBk");
+  memory->create(nPiBk,neigh_total,"nPiBk");
+  memory->create(piB,neigh_total,"piB");
+  memory->create(neigh_flag,neigh_total,"neigh_flag");
+  if(otfly==0) {
+    memory->create(cosAng,cos_total,"BOP:cosAng");
+    memory->create(dcAng,cos_total*2,3,2,"BOP:dcAng");
+    memory->create(disij,3,neigh_total,"disij");
+    memory->create(rij,neigh_total,"rij");
+    memory->create(betaS,neigh_total,"betaS");
+    memory->create(dBetaS,neigh_total,"dBetaS");
+    memory->create(betaP,neigh_total,"betaP");
+    memory->create(dBetaP,neigh_total,"dBetaP");
+    memory->create(repul,neigh_total,"repul");
+    memory->create(dRepul,neigh_total,"dRepul");
+  }
+  update_list=1;
+}
+
+void PairBOP::memory_theta_grow()
+{
+  int nlocal,nghost,nall;
+ 
+  nlocal = atom->nlocal;
+  nghost = atom->nghost;
+  nall = nlocal + nghost;
+  if(maxneigh<8) 
+    neigh_ct=(maxneigh-1)*(maxneigh-1)*(maxneigh-1);
+  else
+    neigh_ct=(maxneigh-1)*(maxneigh-1);
+  memory->grow(itypeSigBk,neigh_total
+      ,neigh_ct,"itypeSigBk");
+  memory->grow(nSigBk,neigh_total,"nSigBk");
+  memory->grow(sigB,neigh_total,"sigB");
+  memory->grow(sigB1,neigh_total,"sigB1");
+  memory->grow(itypePiBk,neigh_total
+      ,neigh_ct,"itypePiBk");
+  memory->grow(nPiBk,neigh_total,"nPiBk");
+  memory->grow(piB,neigh_total,"piB");
+  memory->grow(neigh_flag,neigh_total,"neigh_flag");
+  if(otfly==0) {
+    memory->grow(cosAng,cos_total,"BOP:cosAng");
+    memory->grow(dcAng,cos_total*2,3,2,"BOP:dcAng");
+    memory->grow(disij,3,neigh_total,"disij");
+    memory->grow(rij,neigh_total,"rij");
+    memory->grow(betaS,neigh_total,"betaS");
+    memory->grow(dBetaS,neigh_total,"dBetaS");
+    memory->grow(betaP,neigh_total,"betaP");
+    memory->grow(dBetaP,neigh_total,"dBetaP");
+    memory->grow(repul,neigh_total,"repul");
+    memory->grow(dRepul,neigh_total,"dRepul");
+  }
+  update_list=1;
+}
+
+void PairBOP::memory_theta_destroy()
+{
+
+  memory->destroy(itypeSigBk);
+  memory->destroy(nSigBk);
+  memory->destroy(sigB);
+  memory->destroy(sigB1);
+  memory->destroy(itypePiBk);
+  memory->destroy(nPiBk);
+  memory->destroy(piB);
+  memory->destroy(neigh_flag);
+  if(otfly==0) {
+    memory->destroy(cosAng);
+    memory->destroy(dcAng);
+    memory->destroy(disij);
+    memory->destroy(rij);
+    memory->destroy(betaS);
+    memory->destroy(dBetaS);
+    memory->destroy(betaP);
+    memory->destroy(dBetaP);
+    memory->destroy(repul);
+    memory->destroy(dRepul);
+  }
+ update_list=0;
+}
+
+void PairBOP::create_pi(int n_tot)
+{
+  bt_pi = (B_PI *) memory->smalloc(n_tot*sizeof(B_PI),"BOP:bt_pi");
+  allocate_pi=1;
+}
+
+void PairBOP::create_sigma(int n_tot)
+{
+  bt_sg = (B_SG *) memory->smalloc(n_tot*sizeof(B_SG),"BOP:bt_sg");
+  allocate_sigma=1;
+}
+
+void PairBOP::destroy_pi()
+{
+  memory->destroy(bt_pi);
+  allocate_pi=0;
+}
+
+void PairBOP::destroy_sigma()
+{
+  memory->destroy(bt_sg);
+  allocate_sigma=0;
+}
+
+void PairBOP::grow_pi(int n1, int n2)
+{
+  int i,j;
+  B_PI *bt_temp;
+  bt_temp = (B_PI *) memory->smalloc(n1*sizeof(B_PI),"BOP:b_temp");
+  for(i=0;i<n1;i++) {
+    bt_temp[i].temp = bt_pi[i].temp;
+    bt_temp[i].i = bt_pi[i].i;
+    bt_temp[i].j = bt_pi[i].j;
+    for(j=0;j<3;j++) {
+      bt_temp[i].dAA[j] = bt_pi[i].dAA[j];
+      bt_temp[i].dBB[j] = bt_pi[i].dBB[j];
+      bt_temp[i].dPiB[j] = bt_pi[i].dPiB[j];
+    }
+  }
+  memory->destroy(bt_pi);
+  bt_pi=NULL;
+  bt_pi = (B_PI *) memory->smalloc(n2*sizeof(B_PI),"BOP:bt_pi");
+  for(i=0;i<n1;i++) {
+    bt_pi[i].temp = bt_temp[i].temp;
+    bt_pi[i].i = bt_temp[i].i;
+    bt_pi[i].j = bt_temp[i].j;
+    for(j=0;j<3;j++) {
+      bt_pi[i].dAA[j] = bt_temp[i].dAA[j];
+      bt_pi[i].dBB[j] = bt_temp[i].dBB[j];
+      bt_pi[i].dPiB[j] = bt_temp[i].dPiB[j];
+    }
+  }
+  for(i=n1;i<n2;i++) {
+    bt_pi[i].i = -1;
+    bt_pi[i].j = -1;
+    for(j=0;j<3;j++) {
+      bt_pi[i].dAA[j] = 0.0;
+      bt_pi[i].dBB[j] = 0.0;
+      bt_pi[i].dPiB[j] = 0.0;
+    }
+  }
+  memory->destroy(bt_temp);
+}
+
+void PairBOP::grow_sigma(int n1,int n2)
+{
+  int i,j;
+  B_SG *bt_temp;
+  bt_temp = (B_SG *) memory->smalloc(n1*sizeof(B_SG),"BOP:bt_temp");
+  for(i=0;i<n1;i++) {
+    bt_temp[i].temp = bt_sg[i].temp;
+    bt_temp[i].i = bt_sg[i].i;
+    bt_temp[i].j = bt_sg[i].j;
+    for(j=0;j<3;j++) {
+      bt_temp[i].dAA[j] = bt_sg[i].dAA[j];
+      bt_temp[i].dBB[j] = bt_sg[i].dBB[j];
+      bt_temp[i].dCC[j] = bt_sg[i].dCC[j];
+      bt_temp[i].dDD[j] = bt_sg[i].dDD[j];
+      bt_temp[i].dEE[j] = bt_sg[i].dEE[j];
+      bt_temp[i].dEE1[j] = bt_sg[i].dEE1[j];
+      bt_temp[i].dFF[j] = bt_sg[i].dFF[j];
+      bt_temp[i].dAAC[j] = bt_sg[i].dAAC[j];
+      bt_temp[i].dBBC[j] = bt_sg[i].dBBC[j];
+      bt_temp[i].dCCC[j] = bt_sg[i].dCCC[j];
+      bt_temp[i].dDDC[j] = bt_sg[i].dDDC[j];
+      bt_temp[i].dEEC[j] = bt_sg[i].dEEC[j];
+      bt_temp[i].dFFC[j] = bt_sg[i].dFFC[j];
+      bt_temp[i].dGGC[j] = bt_sg[i].dGGC[j];
+      bt_temp[i].dUT[j] = bt_sg[i].dUT[j];
+      bt_temp[i].dSigB1[j] = bt_sg[i].dSigB1[j];
+      bt_temp[i].dSigB[j] = bt_sg[i].dSigB[j];
+    }
+  }
+  memory->destroy(bt_sg);
+  bt_sg=NULL;
+  bt_sg = (B_SG *) memory->smalloc(n2*sizeof(B_SG),"BOP:bt_sg");
+  for(i=0;i<n1;i++) {
+    bt_sg[i].temp = bt_temp[i].temp;
+    bt_sg[i].i = bt_temp[i].i;
+    bt_sg[i].j = bt_temp[i].j;
+    for(j=0;j<3;j++) {
+      bt_sg[i].dAA[j] = bt_temp[i].dAA[j];
+      bt_sg[i].dBB[j] = bt_temp[i].dBB[j];
+      bt_sg[i].dCC[j] = bt_temp[i].dCC[j];
+      bt_sg[i].dDD[j] = bt_temp[i].dDD[j];
+      bt_sg[i].dEE[j] = bt_temp[i].dEE[j];
+      bt_sg[i].dEE1[j] = bt_temp[i].dEE1[j];
+      bt_sg[i].dFF[j] = bt_temp[i].dFF[j];
+      bt_sg[i].dAAC[j] = bt_temp[i].dAAC[j];
+      bt_sg[i].dBBC[j] = bt_temp[i].dBBC[j];
+      bt_sg[i].dCCC[j] = bt_temp[i].dCCC[j];
+      bt_sg[i].dDDC[j] = bt_temp[i].dDDC[j];
+      bt_sg[i].dEEC[j] = bt_temp[i].dEEC[j];
+      bt_sg[i].dFFC[j] = bt_temp[i].dFFC[j];
+      bt_sg[i].dGGC[j] = bt_temp[i].dGGC[j];
+      bt_sg[i].dUT[j] = bt_temp[i].dUT[j];
+      bt_sg[i].dSigB1[j] = bt_temp[i].dSigB1[j];
+      bt_sg[i].dSigB[j] = bt_temp[i].dSigB[j];
+    }
+  }
+  for(i=n1;i<n2;i++) {
+    bt_sg[i].i = -1;
+    bt_sg[i].j = -1;
+    for(j=0;j<3;j++) {
+      bt_sg[i].dAA[j] = 0.0;
+      bt_sg[i].dBB[j] = 0.0;
+      bt_sg[i].dCC[j] = 0.0;
+      bt_sg[i].dDD[j] = 0.0;
+      bt_sg[i].dEE[j] = 0.0;
+      bt_sg[i].dEE1[j] = 0.0;
+      bt_sg[i].dFF[j] = 0.0;
+      bt_sg[i].dAAC[j] = 0.0;
+      bt_sg[i].dBBC[j] = 0.0;
+      bt_sg[i].dCCC[j] = 0.0;
+      bt_sg[i].dDDC[j] = 0.0;
+      bt_sg[i].dEEC[j] = 0.0;
+      bt_sg[i].dFFC[j] = 0.0;
+      bt_sg[i].dGGC[j] = 0.0;
+      bt_sg[i].dUT[j] = 0.0;
+      bt_sg[i].dSigB1[j] = 0.0;
+      bt_sg[i].dSigB[j] = 0.0;
+    }
+  }
+  memory->destroy(bt_temp);
+}
diff --git a/src/MANYBODY/pair_bop.h b/src/MANYBODY/pair_bop.h
new file mode 100644
index 0000000000..9e944b3eb3
--- /dev/null
+++ b/src/MANYBODY/pair_bop.h
@@ -0,0 +1,216 @@
+/* ----------------------------------------------------------------------
+   LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
+   http://lammps.sandia.gov, Sandia National Laboratories
+   Steve Plimpton, sjplimp@sandia.gov
+
+   Copyright (2003) Sandia Corporation.  Under the terms of Contract
+   DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
+   certain rights in this software.  This software is distributed under
+   the GNU General Public License.
+
+   See the README file in the top-level LAMMPS directory.
+------------------------------------------------------------------------- */
+
+#ifdef PAIR_CLASS
+
+PairStyle(bop,PairBOP)
+
+#else
+
+#ifndef LMP_PAIR_BOP_H
+#define LMP_PAIR_BOP_H
+
+#include "pair.h"
+#include "update.h"
+
+namespace LAMMPS_NS {
+
+class PairBOP : public Pair {
+ public:
+  PairBOP(class LAMMPS *);
+  virtual ~PairBOP();
+  void compute(int, int);
+  void settings(int, char **);
+  void coeff(int, char **);
+  void init_style();
+  double init_one(int, int);
+  double memory_usage();
+
+ private:
+  int me;
+  int maxneigh;                    // maximum size of neighbor list on this processor
+  int update_list;                 // check for changing maximum size of neighbor list
+  int maxbopn;                     // maximum size of bop neighbor list for allocation
+  int maxnall;                     // maximum size of bop neighbor list for allocation
+  int *map;                        // mapping from atom types to elements
+  int nelements;		   // # of unique elments
+  int nr;                     // increments for the BOP potential
+  int nBOt;                   // second BO increments
+  int bop_types;                   // number of elments in potential
+  int npairs;                      // number of element pairs
+  char **elements;		   // names of unique elements 
+  int ***elem2param;		   
+  int nparams;
+  int bop_step;
+  int allocate_pi;
+  int allocate_sigma;
+  int allocate_neigh;
+  int nb_pi,nb_sg;
+
+  int *BOP_index;                 // index for neighbor list position
+  int neigh_total;                // total number of neighbors stored
+  int *cos_index;                 // index for neighbor cosine if not using on the fly
+  int *neigh_flag;                 // index for neighbor cosine if not using on the fly
+  int cos_total;                  // number of cosines stored if not using on the fly
+  int neigh_ct;                  //  limit for large arrays
+
+/*Parameters variables*/ 
+
+  int ncutoff,nfunc;
+  int a_flag;
+  double *pi_a,*pro_delta,*pi_delta;
+  double *pi_p,*pi_c,*sigma_r0,*pi_r0,*phi_r0;
+  double *sigma_rc,*pi_rc,*phi_rc,*r1,*sigma_beta0;
+  double *pi_beta0,*phi0,*sigma_n,*pi_n,*phi_m;
+  double *sigma_nc,*pi_nc,*phi_nc;
+  double *pro,*sigma_delta,*sigma_c,*sigma_a;
+  double ***sigma_g0,***sigma_g1,***sigma_g2,***sigma_g3;
+  double ***sigma_g4,*sigma_f,*sigma_k,*small3;
+  double small1,small2,small3g,small4,small5,small6,small7;
+  double which,alpha,alpha1,beta1,gamma1,alpha2,beta2,alpha3;
+  double beta3,rsmall,rbig,rcore;
+  char **words;
+ 
+  double cutmax;		//max cutoff for all elements 
+  int otfly;			//Defines whether to do on the fly
+                                //calculations of angles and distances
+                                //on the fly will slow down calculations
+                                //but requires less memory on = 1, off=0
+
+  int table;			//determines the method for reading in 
+                                //potential parameters a preset table
+                                //or generate the tables using a spline
+
+/* Neigh variables */
+ 
+  double *rcut,*dr,*rdr;
+  double **disij,*rij;
+
+/*Triple variables */
+ 
+  double *cosAng,***dcosAng,***dcAng;
+ 
+/*Double variables */
+ 
+  double *betaS,*dBetaS,*betaP;
+  double *dBetaP,*repul,*dRepul;
+  
+/*Sigma variables */
+ 
+  int **itypeSigBk,*nSigBk;
+  double *sigB;
+  double *sigB1;
+
+  
+/*Pi variables */
+ 
+  int **itypePiBk,*nPiBk;
+  double *piB;
+   
+/*Grids1 variables */
+ 
+  double **pBetaS,**pBetaS1,**pBetaS2,**pBetaS3;
+  double **pBetaS4,**pBetaS5,**pBetaS6;
+ 
+/*Grids2 variables */
+ 
+  double **pBetaP,**pBetaP1,**pBetaP2,**pBetaP3;
+  double **pBetaP4,**pBetaP5,**pBetaP6;
+ 
+/*Grids3 variables */
+ 
+  double **pRepul,**pRepul1,**pRepul2,**pRepul3;
+  double **pRepul4,**pRepul5,**pRepul6;
+ 
+/*Grids4 variables */
+ 
+  double **FsigBO,**FsigBO1,**FsigBO2,**FsigBO3;
+  double **FsigBO4,**FsigBO5,**FsigBO6;
+  double dBO,rdBO; 
+  
+/* End of BOP variables */
+
+  double **rcmin,**rcmax,**rcmaxp;
+  struct B_PI{
+    double dAA[3];
+    double dBB[3];
+    double dPiB[3];
+    int temp;
+    int i;
+    int j;
+  };
+  B_PI *bt_pi;
+
+  struct B_SG{
+    double dAA[3];
+    double dBB[3];
+    double dCC[3];
+    double dDD[3];
+    double dEE[3];
+    double dEE1[3];
+    double dFF[3];
+    double dAAC[3];
+    double dBBC[3];
+    double dCCC[3];
+    double dDDC[3];
+    double dEEC[3];
+    double dFFC[3];
+    double dGGC[3];
+    double dUT[3];
+    double dSigB1[3];
+    double dSigB[3];
+    int temp;
+    int i;
+    int j;
+  };
+  B_SG *bt_sg;
+
+  void setPbetaS();
+  void setPbetaP();
+  void setPrepul();
+  void setSign();
+  void gneigh();
+  void theta();
+  void theta_mod();
+  void sigmaBo();
+  void PiBo();
+  void sigmaBo_otf();
+  void PiBo_otf();
+  void sigmaBo_noa();
+  void sigmaBo_noa_otf();
+  void memory_theta_create();
+  void memory_theta_destroy();
+  void memory_theta_grow();
+  double cutoff(double, double, int, double);
+  double betaSfunc(int, double);
+  double dBetaSfunc(int, double, double, double);
+  double betaPfunc(int, double);
+  double dBetaPfunc(int, double, double, double);
+  double repulfunc(int, double);
+  double dRepulfunc(int, double, double, double);
+
+  void read_file(char *);
+  void read_table(char *);
+  void allocate();
+  void create_pi(int);
+  void create_sigma(int);
+  void destroy_pi();
+  void destroy_sigma();
+  void grow_pi(int,int);
+  void grow_sigma(int,int);
+};
+
+}
+
+#endif
+#endif
diff --git a/src/MOLECULE/atom_vec_angle.cpp b/src/MOLECULE/atom_vec_angle.cpp
index ceda777518..8b9b4dbfa0 100644
--- a/src/MOLECULE/atom_vec_angle.cpp
+++ b/src/MOLECULE/atom_vec_angle.cpp
@@ -578,7 +578,7 @@ int AtomVecAngle::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
 
@@ -701,7 +701,7 @@ int AtomVecAngle::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -748,7 +748,8 @@ void AtomVecAngle::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -766,7 +767,7 @@ void AtomVecAngle::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecAngle::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecAngle::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/MOLECULE/atom_vec_angle.h b/src/MOLECULE/atom_vec_angle.h
index 56a6e35978..7a39863f22 100644
--- a/src/MOLECULE/atom_vec_angle.h
+++ b/src/MOLECULE/atom_vec_angle.h
@@ -49,12 +49,13 @@ class AtomVecAngle : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   int *molecule;
   int **nspecial,**special;
diff --git a/src/MOLECULE/atom_vec_bond.cpp b/src/MOLECULE/atom_vec_bond.cpp
index ee4aabb6f6..60f6882cba 100644
--- a/src/MOLECULE/atom_vec_bond.cpp
+++ b/src/MOLECULE/atom_vec_bond.cpp
@@ -549,7 +549,7 @@ int AtomVecBond::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
 
@@ -656,7 +656,7 @@ int AtomVecBond::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -695,7 +695,8 @@ void AtomVecBond::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -712,7 +713,7 @@ void AtomVecBond::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecBond::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecBond::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/MOLECULE/atom_vec_bond.h b/src/MOLECULE/atom_vec_bond.h
index 19b301441c..ed437027a1 100644
--- a/src/MOLECULE/atom_vec_bond.h
+++ b/src/MOLECULE/atom_vec_bond.h
@@ -48,12 +48,13 @@ class AtomVecBond : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   int *molecule;
   int **nspecial,**special;
diff --git a/src/MOLECULE/atom_vec_full.cpp b/src/MOLECULE/atom_vec_full.cpp
index 0a8a3785de..51717cbea6 100644
--- a/src/MOLECULE/atom_vec_full.cpp
+++ b/src/MOLECULE/atom_vec_full.cpp
@@ -666,7 +666,7 @@ int AtomVecFull::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   q[nlocal] = buf[m++];
   molecule[nlocal] = static_cast<int> (buf[m++]);
@@ -828,7 +828,7 @@ int AtomVecFull::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -894,7 +894,8 @@ void AtomVecFull::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -915,7 +916,7 @@ void AtomVecFull::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecFull::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecFull::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/MOLECULE/atom_vec_full.h b/src/MOLECULE/atom_vec_full.h
index f21c736acf..14e25237de 100644
--- a/src/MOLECULE/atom_vec_full.h
+++ b/src/MOLECULE/atom_vec_full.h
@@ -49,12 +49,13 @@ class AtomVecFull : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double *q;
   int *molecule;
diff --git a/src/MOLECULE/atom_vec_molecular.cpp b/src/MOLECULE/atom_vec_molecular.cpp
index c2d2ca9fc5..668f7551bb 100644
--- a/src/MOLECULE/atom_vec_molecular.cpp
+++ b/src/MOLECULE/atom_vec_molecular.cpp
@@ -653,7 +653,7 @@ int AtomVecMolecular::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
 
@@ -813,7 +813,7 @@ int AtomVecMolecular::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -878,7 +878,8 @@ void AtomVecMolecular::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -898,7 +899,7 @@ void AtomVecMolecular::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecMolecular::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecMolecular::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/MOLECULE/atom_vec_molecular.h b/src/MOLECULE/atom_vec_molecular.h
index 046d9cc0a7..3da1a5fe02 100644
--- a/src/MOLECULE/atom_vec_molecular.h
+++ b/src/MOLECULE/atom_vec_molecular.h
@@ -48,12 +48,13 @@ class AtomVecMolecular : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   int *molecule;
   int **nspecial,**special;
diff --git a/src/PERI/atom_vec_peri.cpp b/src/PERI/atom_vec_peri.cpp
index 586823e71d..27f7c65cec 100644
--- a/src/PERI/atom_vec_peri.cpp
+++ b/src/PERI/atom_vec_peri.cpp
@@ -601,7 +601,7 @@ int AtomVecPeri::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   vfrac[nlocal] = buf[m++];
   rmass[nlocal] = buf[m++];
@@ -695,7 +695,7 @@ int AtomVecPeri::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -733,7 +733,8 @@ void AtomVecPeri::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -753,7 +754,7 @@ void AtomVecPeri::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecPeri::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecPeri::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/PERI/atom_vec_peri.h b/src/PERI/atom_vec_peri.h
index b7479414de..185eca375c 100755
--- a/src/PERI/atom_vec_peri.h
+++ b/src/PERI/atom_vec_peri.h
@@ -50,12 +50,13 @@ class AtomVecPeri : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double *vfrac,*density,*rmass,*s0,**x0;
 };
diff --git a/src/POEMS/fix_poems.cpp b/src/POEMS/fix_poems.cpp
index 73330823df..4f54b55b9f 100644
--- a/src/POEMS/fix_poems.cpp
+++ b/src/POEMS/fix_poems.cpp
@@ -360,7 +360,7 @@ void FixPOEMS::init()
   // only count joint atoms in 1st body
 
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double **x = atom->x;
   double **v = atom->v;
@@ -379,9 +379,9 @@ void FixPOEMS::init()
   for (i = 0; i < nlocal; i++) {
     if (natom2body[i]) {
       ibody = atom2body[i][0];
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       massone = mass[type[i]];
       sum[ibody][0] += (x[i][0] + xbox*xprd) * massone;
       sum[ibody][1] += (x[i][1] + ybox*yprd) * massone;
@@ -416,9 +416,9 @@ void FixPOEMS::init()
     if (natom2body[i]) {
       ibody = atom2body[i][0];
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xcm[ibody][0];
       dy = x[i][1] + ybox*yprd - xcm[ibody][1];
       dz = x[i][2] + zbox*zprd - xcm[ibody][2];
@@ -511,9 +511,9 @@ void FixPOEMS::init()
     if (natom2body[i]) {
       ibody = atom2body[i][0];
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xcm[ibody][0];
       dy = x[i][1] + ybox*yprd - xcm[ibody][1];
       dz = x[i][2] + zbox*zprd - xcm[ibody][2];
@@ -544,9 +544,9 @@ void FixPOEMS::init()
     if (natom2body[i]) {
       ibody = atom2body[i][0];
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xcm[ibody][0];
       dy = x[i][1] + ybox*yprd - xcm[ibody][1];
       dz = x[i][2] + zbox*zprd - xcm[ibody][2];
@@ -596,7 +596,7 @@ void FixPOEMS::setup(int vflag)
   // only count joint atoms in 1st body
 
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double **x = atom->x;
   double **v = atom->v;
@@ -617,9 +617,9 @@ void FixPOEMS::setup(int vflag)
       ibody = atom2body[i][0];
       massone = mass[type[i]];
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xcm[ibody][0];
       dy = x[i][1] + ybox*yprd - xcm[ibody][1];
       dz = x[i][2] + zbox*zprd - xcm[ibody][2];
@@ -710,7 +710,7 @@ void FixPOEMS::post_force(int vflag)
   int xbox,ybox,zbox;
   double dx,dy,dz;
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
   double **f = atom->f;
   int nlocal = atom->nlocal;
@@ -730,9 +730,9 @@ void FixPOEMS::post_force(int vflag)
       sum[ibody][1] += f[i][1];
       sum[ibody][2] += f[i][2];
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xcm[ibody][0];
       dy = x[i][1] + ybox*yprd - xcm[ibody][1];
       dz = x[i][2] + zbox*zprd - xcm[ibody][2];
@@ -1341,7 +1341,7 @@ void FixPOEMS::set_xv()
   double x0,x1,x2,v0,v1,v2,fc0,fc1,fc2,massone;
   double vr[6];
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
   double **v = atom->v;
   double **f = atom->f;
@@ -1360,9 +1360,9 @@ void FixPOEMS::set_xv()
     if (natom2body[i] == 0) continue;
     ibody = atom2body[i][0];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     // save old positions and velocities for virial
 
@@ -1445,7 +1445,7 @@ void FixPOEMS::set_v()
   double **x = atom->x;
   double **v = atom->v;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double xprd = domain->xprd;
@@ -1493,9 +1493,9 @@ void FixPOEMS::set_v()
       fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
       fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
       x0 = x[i][0] + xbox*xprd;
       x1 = x[i][1] + ybox*yprd;
diff --git a/src/REPLICA/compute_event_displace.cpp b/src/REPLICA/compute_event_displace.cpp
index 8cfe64461d..45d4341270 100644
--- a/src/REPLICA/compute_event_displace.cpp
+++ b/src/REPLICA/compute_event_displace.cpp
@@ -96,7 +96,7 @@ double ComputeEventDisplace::compute_scalar()
 
   double **x = atom->x;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double *h = domain->h;
@@ -109,9 +109,9 @@ double ComputeEventDisplace::compute_scalar()
   if (triclinic == 0) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         dx = x[i][0] + xbox*xprd - xevent[i][0];
         dy = x[i][1] + ybox*yprd - xevent[i][1];
         dz = x[i][2] + zbox*zprd - xevent[i][2];
@@ -124,9 +124,9 @@ double ComputeEventDisplace::compute_scalar()
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         dx = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox - xevent[i][0];
         dy = x[i][1] + h[1]*ybox + h[3]*zbox - xevent[i][1];
         dz = x[i][2] + h[2]*zbox - xevent[i][2];
diff --git a/src/REPLICA/fix_event.cpp b/src/REPLICA/fix_event.cpp
index 4f59530573..ff43036035 100644
--- a/src/REPLICA/fix_event.cpp
+++ b/src/REPLICA/fix_event.cpp
@@ -81,7 +81,7 @@ int FixEvent::setmask()
 void FixEvent::store_event()
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++)
@@ -97,7 +97,7 @@ void FixEvent::store_event()
 void FixEvent::restore_event()
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
@@ -108,9 +108,10 @@ void FixEvent::restore_event()
     // Since xevent is unwrapped coordinate, need to
     // adjust image flags when remapping
 
-    image[i] = (512 << 20) | (512 << 10) | 512;
+    image[i] = ((tagint) IMGMAX << IMG2BITS) | 
+      ((tagint) IMGMASK << IMGBITS) | IMGMASK;
     domain->remap(x[i],image[i]);
-    //    domain->remap(x[i]);
+    // domain->remap(x[i]);
   }
 
 }
@@ -125,7 +126,7 @@ void FixEvent::store_state()
 {
   double **x = atom->x;
   double **v = atom->v;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
@@ -148,7 +149,7 @@ void FixEvent::restore_state()
 {
   double **x = atom->x;
   double **v = atom->v;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
diff --git a/src/REPLICA/tad.cpp b/src/REPLICA/tad.cpp
index 9102bac1a0..05170719ac 100644
--- a/src/REPLICA/tad.cpp
+++ b/src/REPLICA/tad.cpp
@@ -830,7 +830,7 @@ void TAD::revert()
 {
   double **x = atom->x;
   double **v = atom->v;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double **array_atom = fix_revert->array_atom;
@@ -839,9 +839,10 @@ void TAD::revert()
     x[i][0] = array_atom[i][0];
     x[i][1] = array_atom[i][1];
     x[i][2] = array_atom[i][2];
-    image[i] = ((int(array_atom[i][5]) + 512 & 1023) << 20) |
-      ((int(array_atom[i][4]) + 512 & 1023) << 10) |
-      (int(array_atom[i][3]) + 512 & 1023);
+    image[i] = 
+      ((int(array_atom[i][5]) + (tagint) IMGMAX & IMGMASK) << IMG2BITS) |
+      ((int(array_atom[i][4]) + (tagint) IMGMAX & IMGMASK) << IMGBITS) |
+      (int(array_atom[i][3]) + IMGMAX & IMGMASK);
     v[i][0] = -array_atom[i][6];
     v[i][1] = -array_atom[i][7];
     v[i][2] = -array_atom[i][8];
diff --git a/src/USER-AWPMD/atom_vec_wavepacket.cpp b/src/USER-AWPMD/atom_vec_wavepacket.cpp
index 52aa2c1822..1be877c021 100644
--- a/src/USER-AWPMD/atom_vec_wavepacket.cpp
+++ b/src/USER-AWPMD/atom_vec_wavepacket.cpp
@@ -728,7 +728,7 @@ int AtomVecWavepacket::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   q[nlocal] = buf[m++];
   spin[nlocal] = static_cast<int> (buf[m++]);
   eradius[nlocal] = buf[m++];
@@ -824,7 +824,7 @@ int AtomVecWavepacket::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -865,7 +865,8 @@ void AtomVecWavepacket::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -888,7 +889,7 @@ void AtomVecWavepacket::create_atom(int itype, double *coord)
    AWPMD: 0-tag 1-type 2-q 3-spin 4-eradius 5-etag 6-cs_re 7-cs_im
 ------------------------------------------------------------------------- */
 
-void AtomVecWavepacket::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecWavepacket::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
 
diff --git a/src/USER-AWPMD/atom_vec_wavepacket.h b/src/USER-AWPMD/atom_vec_wavepacket.h
index f98caca33c..dd8b61c6fc 100644
--- a/src/USER-AWPMD/atom_vec_wavepacket.h
+++ b/src/USER-AWPMD/atom_vec_wavepacket.h
@@ -58,14 +58,15 @@ public:
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   void data_vel(int, char **);
   int data_vel_hybrid(int, char **);
   bigint memory_usage();
 
 private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
 
   ///\en spin: -1 or 1 for electron, 0 for ion (compatible with eff)
diff --git a/src/USER-EFF/atom_vec_electron.cpp b/src/USER-EFF/atom_vec_electron.cpp
index 9cbdf22cbb..b56fce6202 100644
--- a/src/USER-EFF/atom_vec_electron.cpp
+++ b/src/USER-EFF/atom_vec_electron.cpp
@@ -607,7 +607,7 @@ int AtomVecElectron::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   q[nlocal] = buf[m++];
   spin[nlocal] = static_cast<int> (buf[m++]);
   eradius[nlocal] = buf[m++];
@@ -695,7 +695,7 @@ int AtomVecElectron::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -731,7 +731,8 @@ void AtomVecElectron::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -749,7 +750,7 @@ void AtomVecElectron::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecElectron::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecElectron::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
 
diff --git a/src/USER-EFF/atom_vec_electron.h b/src/USER-EFF/atom_vec_electron.h
index cfe8f3ea9e..73dd126a62 100644
--- a/src/USER-EFF/atom_vec_electron.h
+++ b/src/USER-EFF/atom_vec_electron.h
@@ -53,14 +53,15 @@ class AtomVecElectron : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   void data_vel(int, char **);
   int data_vel_hybrid(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   int *spin;
   double *q,*eradius,*ervel,*erforce;
diff --git a/src/USER-MISC/compute_temp_rotate.cpp b/src/USER-MISC/compute_temp_rotate.cpp
index 69519249c7..b796345404 100644
--- a/src/USER-MISC/compute_temp_rotate.cpp
+++ b/src/USER-MISC/compute_temp_rotate.cpp
@@ -109,7 +109,7 @@ double ComputeTempRotate::compute_scalar()
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -124,9 +124,9 @@ double ComputeTempRotate::compute_scalar()
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
@@ -178,7 +178,7 @@ void ComputeTempRotate::compute_vector()
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -194,9 +194,9 @@ void ComputeTempRotate::compute_vector()
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
diff --git a/src/USER-MISC/fix_addtorque.cpp b/src/USER-MISC/fix_addtorque.cpp
index 9d0d621fe7..7862b2e499 100644
--- a/src/USER-MISC/fix_addtorque.cpp
+++ b/src/USER-MISC/fix_addtorque.cpp
@@ -162,7 +162,7 @@ void FixAddTorque::post_force(int vflag)
   double **f = atom->f;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -200,9 +200,9 @@ void FixAddTorque::post_force(int vflag)
   tlocal[0] = tlocal[1] = tlocal[2] = 0.0;
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
@@ -222,9 +222,9 @@ void FixAddTorque::post_force(int vflag)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
diff --git a/src/USER-MISC/fix_imd.cpp b/src/USER-MISC/fix_imd.cpp
index 69379c0f52..87c950d00d 100644
--- a/src/USER-MISC/fix_imd.cpp
+++ b/src/USER-MISC/fix_imd.cpp
@@ -823,7 +823,7 @@ void FixIMD::post_force(int vflag)
 
   int *tag = atom->tag;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
   int *mask  = atom->mask;
   struct commdata *buf;
@@ -1036,9 +1036,9 @@ void FixIMD::post_force(int vflag)
         if (mask[i] & groupbit) {
           const int j = 3*inthash_lookup((inthash_t *)idmap, tag[i]);
           if (j != HASH_FAIL) {
-            int ix = (image[i] & 1023) - 512;
-            int iy = (image[i] >> 10 & 1023) - 512;
-            int iz = (image[i] >> 20) - 512;
+            int ix = (image[i] & IMGMASK) - IMGMAX;
+            int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+            int iz = (image[i] >> IMG2BITS) - IMGMAX;
 
             if (domain->triclinic) {
               recvcoord[j]   = x[i][0] + ix * xprd + iy * xy + iz * xz;
@@ -1112,9 +1112,9 @@ void FixIMD::post_force(int vflag)
 
       for (i=0; i<nlocal; ++i) {
         if (mask[i] & groupbit) {
-          int ix = (image[i] & 1023) - 512;
-          int iy = (image[i] >> 10 & 1023) - 512;
-          int iz = (image[i] >> 20) - 512;
+          int ix = (image[i] & IMGMASK) - IMGMAX;
+          int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+          int iz = (image[i] >> IMG2BITS) - IMGMAX;
 
           if (domain->triclinic) {
             buf[nme].tag = tag[i];
diff --git a/src/USER-MOLFILE/dump_molfile.cpp b/src/USER-MOLFILE/dump_molfile.cpp
index 6a32ac8b1f..1d01884302 100644
--- a/src/USER-MOLFILE/dump_molfile.cpp
+++ b/src/USER-MOLFILE/dump_molfile.cpp
@@ -308,7 +308,7 @@ void DumpMolfile::pack(int *ids)
   int *tag = atom->tag;
   int *type = atom->type;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -323,9 +323,9 @@ void DumpMolfile::pack(int *ids)
 
     for (int i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
-        int ix = (image[i] & 1023) - 512;
-        int iy = (image[i] >> 10 & 1023) - 512;
-        int iz = (image[i] >> 20) - 512;
+        int ix = (image[i] & IMGMASK) - IMGMAX;
+        int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        int iz = (image[i] >> IMG2BITS) - IMGMAX;
 
         buf[m++] = type[i];
         if (domain->triclinic) {
diff --git a/src/USER-SPH/atom_vec_meso.cpp b/src/USER-SPH/atom_vec_meso.cpp
index 4bf403daec..177d49262b 100644
--- a/src/USER-SPH/atom_vec_meso.cpp
+++ b/src/USER-SPH/atom_vec_meso.cpp
@@ -630,7 +630,7 @@ int AtomVecMeso::unpack_exchange(double *buf) {
         tag[nlocal] = static_cast<int> (buf[m++]);
         type[nlocal] = static_cast<int> (buf[m++]);
         mask[nlocal] = static_cast<int> (buf[m++]);
-        image[nlocal] = static_cast<int> (buf[m++]);
+        image[nlocal] = static_cast<tagint> (buf[m++]);
         rho[nlocal] = buf[m++];
         e[nlocal] = buf[m++];
         cv[nlocal] = buf[m++];
@@ -718,7 +718,7 @@ int AtomVecMeso::unpack_restart(double *buf) {
         tag[nlocal] = static_cast<int> (buf[m++]);
         type[nlocal] = static_cast<int> (buf[m++]);
         mask[nlocal] = static_cast<int> (buf[m++]);
-        image[nlocal] = static_cast<int> (buf[m++]);
+        image[nlocal] = static_cast<tagint> (buf[m++]);
         v[nlocal][0] = buf[m++];
         v[nlocal][1] = buf[m++];
         v[nlocal][2] = buf[m++];
@@ -756,7 +756,8 @@ void AtomVecMeso::create_atom(int itype, double *coord) {
         x[nlocal][1] = coord[1];
         x[nlocal][2] = coord[2];
         mask[nlocal] = 1;
-        image[nlocal] = (512 << 20) | (512 << 10) | 512;
+        image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+          ((tagint) IMGMAX << IMGBITS) | IMGMAX;
         v[nlocal][0] = 0.0;
         v[nlocal][1] = 0.0;
         v[nlocal][2] = 0.0;
@@ -777,7 +778,7 @@ void AtomVecMeso::create_atom(int itype, double *coord) {
  initialize other atom quantities
  ------------------------------------------------------------------------- */
 
-void AtomVecMeso::data_atom(double *coord, int imagetmp, char **values) {
+void AtomVecMeso::data_atom(double *coord, tagint imagetmp, char **values) {
         int nlocal = atom->nlocal;
         if (nlocal == nmax)
                 grow(0);
diff --git a/src/USER-SPH/atom_vec_meso.h b/src/USER-SPH/atom_vec_meso.h
index eeb3bb456e..97ea42ac5c 100644
--- a/src/USER-SPH/atom_vec_meso.h
+++ b/src/USER-SPH/atom_vec_meso.h
@@ -57,12 +57,13 @@ class AtomVecMeso : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double *rho, *drho, *e, *de, *cv;
   double **vest; // estimated velocity during force computation
diff --git a/src/XTC/dump_xtc.cpp b/src/XTC/dump_xtc.cpp
index 2ff16b3881..4dd5e66dd0 100644
--- a/src/XTC/dump_xtc.cpp
+++ b/src/XTC/dump_xtc.cpp
@@ -195,7 +195,7 @@ void DumpXTC::pack(int *ids)
 
   int *tag = atom->tag;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -210,9 +210,9 @@ void DumpXTC::pack(int *ids)
 
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        int ix = (image[i] & 1023) - 512;
-        int iy = (image[i] >> 10 & 1023) - 512;
-        int iz = (image[i] >> 20) - 512;
+        int ix = (image[i] & IMGMASK) - IMGMAX;
+        int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        int iz = (image[i] >> IMG2BITS) - IMGMAX;
 
         if (domain->triclinic) {
           buf[m++] = sfactor * (x[i][0] + ix * xprd + iy * xy + iz * xz);
@@ -359,7 +359,7 @@ static int *buf = NULL;
 static int magicints[] = {
   0, 0, 0, 0, 0, 0, 0, 0, 0,
   8, 10, 12, 16, 20, 25, 32, 40, 50, 64,
-  80, 101, 128, 161, 203, 256, 322, 406, 512, 645,
+  80, 101, 128, 161, 203, 256, 322, 406, IMGMAX, 645,
   812, 1024, 1290, 1625, 2048, 2580, 3250, 4096, 5060, 6501,
   8192, 10321, 13003, 16384, 20642, 26007, 32768, 41285, 52015, 65536,
   82570, 104031, 131072, 165140, 208063, 262144, 330280, 416127,
diff --git a/src/atom.cpp b/src/atom.cpp
index 760a22db7f..04c9fa1610 100644
--- a/src/atom.cpp
+++ b/src/atom.cpp
@@ -65,7 +65,8 @@ Atom::Atom(LAMMPS *lmp) : Pointers(lmp)
   // initialize atom arrays
   // customize by adding new array
 
-  tag = type = mask = image = NULL;
+  tag = type = mask = NULL;
+  image = NULL;
   x = v = f = NULL;
 
   molecule = NULL;
@@ -464,7 +465,9 @@ void Atom::tag_extend()
 
 int Atom::tag_consecutive()
 {
-  int idmin = MAXTAGINT;
+  // change this when allow tagint = bigint
+  //int idmin = MAXTAGINT;
+  int idmin = MAXSMALLINT;
   int idmax = 0;
 
   for (int i = 0; i < nlocal; i++) {
@@ -513,7 +516,8 @@ int Atom::count_words(const char *line)
 
 void Atom::data_atoms(int n, char *buf)
 {
-  int m,imagedata,xptr,iptr;
+  int m,xptr,iptr;
+  tagint imagedata;
   double xdata[3],lamda[3];
   double *coord;
   char *next;
@@ -593,10 +597,12 @@ void Atom::data_atoms(int n, char *buf)
     }
 
     if (imageflag)
-      imagedata = ((atoi(values[iptr+2]) + 512 & 1023) << 20) |
-        ((atoi(values[iptr+1]) + 512 & 1023) << 10) |
-        (atoi(values[iptr]) + 512 & 1023);
-    else imagedata = (512 << 20) | (512 << 10) | 512;
+      imagedata = 
+        (((tagint) atoi(values[iptr+2]) + IMGMAX & IMGMASK) << IMG2BITS) |
+        (((tagint) atoi(values[iptr+1]) + IMGMASK & IMGMASK) << IMGBITS) |
+        (atoi(values[iptr]) + IMGMASK & IMGMASK);
+    else imagedata = ((tagint) IMGMAX << IMG2BITS) | 
+           ((tagint) IMGMAX << IMGBITS) | IMGMAX;
 
     xdata[0] = atof(values[xptr]);
     xdata[1] = atof(values[xptr+1]);
diff --git a/src/atom.h b/src/atom.h
index 83779da061..4585b4f8b8 100644
--- a/src/atom.h
+++ b/src/atom.h
@@ -44,7 +44,8 @@ class Atom : protected Pointers {
   // per-atom arrays
   // customize by adding new array
 
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
 
   int *molecule;
diff --git a/src/atom_vec.h b/src/atom_vec.h
index b05d4bf4ca..75627a42ef 100644
--- a/src/atom_vec.h
+++ b/src/atom_vec.h
@@ -77,7 +77,7 @@ class AtomVec : protected Pointers {
   virtual int unpack_restart(double *) = 0;
 
   virtual void create_atom(int, double *) = 0;
-  virtual void data_atom(double *, int, char **) = 0;
+  virtual void data_atom(double *, tagint, char **) = 0;
   virtual void data_atom_bonus(int, char **) {}
   virtual int data_atom_hybrid(int, char **) {return 0;}
   virtual void data_vel(int, char **);
diff --git a/src/atom_vec_atomic.cpp b/src/atom_vec_atomic.cpp
index 080a32c23e..740319a6f8 100644
--- a/src/atom_vec_atomic.cpp
+++ b/src/atom_vec_atomic.cpp
@@ -5,7 +5,7 @@
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
-   certain rights in this software.  This software is distributed under
+   certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
@@ -46,7 +46,7 @@ AtomVecAtomic::AtomVecAtomic(LAMMPS *lmp, int narg, char **arg) :
 /* ----------------------------------------------------------------------
    grow atom arrays
    n = 0 grows arrays by DELTA
-   n > 0 allocates arrays to size n
+   n > 0 allocates arrays to size n 
 ------------------------------------------------------------------------- */
 
 void AtomVecAtomic::grow(int n)
@@ -66,7 +66,7 @@ void AtomVecAtomic::grow(int n)
   f = memory->grow(atom->f,nmax*comm->nthreads,3,"atom:f");
 
   if (atom->nextra_grow)
-    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->grow_arrays(nmax);
 }
 
@@ -99,14 +99,14 @@ void AtomVecAtomic::copy(int i, int j, int delflag)
   v[j][2] = v[i][2];
 
   if (atom->nextra_grow)
-    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       modify->fix[atom->extra_grow[iextra]]->copy_arrays(i,j);
 }
 
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_comm(int n, int *list, double *buf,
-                             int pbc_flag, int *pbc)
+			     int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
@@ -142,7 +142,7 @@ int AtomVecAtomic::pack_comm(int n, int *list, double *buf,
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_comm_vel(int n, int *list, double *buf,
-                                 int pbc_flag, int *pbc)
+				 int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz,dvx,dvy,dvz;
@@ -170,32 +170,32 @@ int AtomVecAtomic::pack_comm_vel(int n, int *list, double *buf,
     }
     if (!deform_vremap) {
       for (i = 0; i < n; i++) {
-        j = list[i];
-        buf[m++] = x[j][0] + dx;
-        buf[m++] = x[j][1] + dy;
-        buf[m++] = x[j][2] + dz;
-        buf[m++] = v[j][0];
-        buf[m++] = v[j][1];
-        buf[m++] = v[j][2];
+	j = list[i];
+	buf[m++] = x[j][0] + dx;
+	buf[m++] = x[j][1] + dy;
+	buf[m++] = x[j][2] + dz;
+	buf[m++] = v[j][0];
+	buf[m++] = v[j][1];
+	buf[m++] = v[j][2];
       }
     } else {
       dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
       dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
       dvz = pbc[2]*h_rate[2];
       for (i = 0; i < n; i++) {
-        j = list[i];
-        buf[m++] = x[j][0] + dx;
-        buf[m++] = x[j][1] + dy;
-        buf[m++] = x[j][2] + dz;
-        if (mask[i] & deform_groupbit) {
-          buf[m++] = v[j][0] + dvx;
-          buf[m++] = v[j][1] + dvy;
-          buf[m++] = v[j][2] + dvz;
-        } else {
-          buf[m++] = v[j][0];
-          buf[m++] = v[j][1];
-          buf[m++] = v[j][2];
-        }
+	j = list[i];
+	buf[m++] = x[j][0] + dx;
+	buf[m++] = x[j][1] + dy;
+	buf[m++] = x[j][2] + dz;
+	if (mask[i] & deform_groupbit) {
+	  buf[m++] = v[j][0] + dvx;
+	  buf[m++] = v[j][1] + dvy;
+	  buf[m++] = v[j][2] + dvz;
+	} else {
+	  buf[m++] = v[j][0];
+	  buf[m++] = v[j][1];
+	  buf[m++] = v[j][2];
+	}
       }
     }
   }
@@ -269,7 +269,7 @@ void AtomVecAtomic::unpack_reverse(int n, int *list, double *buf)
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_border(int n, int *list, double *buf,
-                               int pbc_flag, int *pbc)
+			       int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz;
@@ -311,7 +311,7 @@ int AtomVecAtomic::pack_border(int n, int *list, double *buf,
 /* ---------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_border_vel(int n, int *list, double *buf,
-                                   int pbc_flag, int *pbc)
+				   int pbc_flag, int *pbc)
 {
   int i,j,m;
   double dx,dy,dz,dvx,dvy,dvz;
@@ -342,38 +342,38 @@ int AtomVecAtomic::pack_border_vel(int n, int *list, double *buf,
     }
     if (!deform_vremap) {
       for (i = 0; i < n; i++) {
-        j = list[i];
-        buf[m++] = x[j][0] + dx;
-        buf[m++] = x[j][1] + dy;
-        buf[m++] = x[j][2] + dz;
-        buf[m++] = tag[j];
-        buf[m++] = type[j];
-        buf[m++] = mask[j];
-        buf[m++] = v[j][0];
-        buf[m++] = v[j][1];
-        buf[m++] = v[j][2];
+	j = list[i];
+	buf[m++] = x[j][0] + dx;
+	buf[m++] = x[j][1] + dy;
+	buf[m++] = x[j][2] + dz;
+	buf[m++] = tag[j];
+	buf[m++] = type[j];
+	buf[m++] = mask[j];
+	buf[m++] = v[j][0];
+	buf[m++] = v[j][1];
+	buf[m++] = v[j][2];
       }
     } else {
       dvx = pbc[0]*h_rate[0] + pbc[5]*h_rate[5] + pbc[4]*h_rate[4];
       dvy = pbc[1]*h_rate[1] + pbc[3]*h_rate[3];
       dvz = pbc[2]*h_rate[2];
       for (i = 0; i < n; i++) {
-        j = list[i];
-        buf[m++] = x[j][0] + dx;
-        buf[m++] = x[j][1] + dy;
-        buf[m++] = x[j][2] + dz;
-        buf[m++] = tag[j];
-        buf[m++] = type[j];
-        buf[m++] = mask[j];
-        if (mask[i] & deform_groupbit) {
-          buf[m++] = v[j][0] + dvx;
-          buf[m++] = v[j][1] + dvy;
-          buf[m++] = v[j][2] + dvz;
-        } else {
-          buf[m++] = v[j][0];
-          buf[m++] = v[j][1];
-          buf[m++] = v[j][2];
-        }
+	j = list[i];
+	buf[m++] = x[j][0] + dx;
+	buf[m++] = x[j][1] + dy;
+	buf[m++] = x[j][2] + dz;
+	buf[m++] = tag[j];
+	buf[m++] = type[j];
+	buf[m++] = mask[j];
+	if (mask[i] & deform_groupbit) {
+	  buf[m++] = v[j][0] + dvx;
+	  buf[m++] = v[j][1] + dvy;
+	  buf[m++] = v[j][2] + dvz;
+	} else {
+	  buf[m++] = v[j][0];
+	  buf[m++] = v[j][1];
+	  buf[m++] = v[j][2];
+	}
       }
     }
   }
@@ -423,7 +423,7 @@ void AtomVecAtomic::unpack_border_vel(int n, int first, double *buf)
 
 /* ----------------------------------------------------------------------
    pack data for atom I for sending to another proc
-   xyz must be 1st 3 values, so comm::exchange() can test on them
+   xyz must be 1st 3 values, so comm::exchange() can test on them 
 ------------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_exchange(int i, double *buf)
@@ -441,7 +441,7 @@ int AtomVecAtomic::pack_exchange(int i, double *buf)
   buf[m++] = image[i];
 
   if (atom->nextra_grow)
-    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->pack_exchange(i,&buf[m]);
 
   buf[0] = m;
@@ -465,12 +465,12 @@ int AtomVecAtomic::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   if (atom->nextra_grow)
-    for (int iextra = 0; iextra < atom->nextra_grow; iextra++)
+    for (int iextra = 0; iextra < atom->nextra_grow; iextra++) 
       m += modify->fix[atom->extra_grow[iextra]]->
-        unpack_exchange(nlocal,&buf[m]);
+	unpack_exchange(nlocal,&buf[m]);
 
   atom->nlocal++;
   return m;
@@ -489,9 +489,9 @@ int AtomVecAtomic::size_restart()
   int n = 11 * nlocal;
 
   if (atom->nextra_restart)
-    for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+    for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       for (i = 0; i < nlocal; i++)
-        n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
+	n += modify->fix[atom->extra_restart[iextra]]->size_restart(i);
 
   return n;
 }
@@ -499,7 +499,7 @@ int AtomVecAtomic::size_restart()
 /* ----------------------------------------------------------------------
    pack atom I's data for restart file including extra quantities
    xyz must be 1st 3 values, so that read_restart can test on them
-   molecular types may be negative, but write as positive
+   molecular types may be negative, but write as positive   
 ------------------------------------------------------------------------- */
 
 int AtomVecAtomic::pack_restart(int i, double *buf)
@@ -517,7 +517,7 @@ int AtomVecAtomic::pack_restart(int i, double *buf)
   buf[m++] = v[i][2];
 
   if (atom->nextra_restart)
-    for (int iextra = 0; iextra < atom->nextra_restart; iextra++)
+    for (int iextra = 0; iextra < atom->nextra_restart; iextra++) 
       m += modify->fix[atom->extra_restart[iextra]]->pack_restart(i,&buf[m]);
 
   buf[0] = m;
@@ -544,7 +544,7 @@ int AtomVecAtomic::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -575,7 +575,8 @@ void AtomVecAtomic::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -588,7 +589,7 @@ void AtomVecAtomic::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecAtomic::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecAtomic::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
@@ -616,7 +617,7 @@ void AtomVecAtomic::data_atom(double *coord, int imagetmp, char **values)
 }
 
 /* ----------------------------------------------------------------------
-   return # of bytes of allocated memory
+   return # of bytes of allocated memory 
 ------------------------------------------------------------------------- */
 
 bigint AtomVecAtomic::memory_usage()
diff --git a/src/atom_vec_atomic.h b/src/atom_vec_atomic.h
index d7aa50c214..97e6c66887 100644
--- a/src/atom_vec_atomic.h
+++ b/src/atom_vec_atomic.h
@@ -47,11 +47,12 @@ class AtomVecAtomic : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
 };
 
diff --git a/src/atom_vec_charge.cpp b/src/atom_vec_charge.cpp
index b9ec7a1851..bdd90b42dc 100644
--- a/src/atom_vec_charge.cpp
+++ b/src/atom_vec_charge.cpp
@@ -508,7 +508,7 @@ int AtomVecCharge::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   q[nlocal] = buf[m++];
 
@@ -591,7 +591,7 @@ int AtomVecCharge::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -624,7 +624,8 @@ void AtomVecCharge::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -639,7 +640,7 @@ void AtomVecCharge::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecCharge::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecCharge::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/atom_vec_charge.h b/src/atom_vec_charge.h
index bc658a2073..41ee4e214c 100644
--- a/src/atom_vec_charge.h
+++ b/src/atom_vec_charge.h
@@ -49,12 +49,13 @@ class AtomVecCharge : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   bigint memory_usage();
 
  protected:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double *q;
 };
diff --git a/src/atom_vec_ellipsoid.cpp b/src/atom_vec_ellipsoid.cpp
index fc0396ec60..1b57a52b6f 100755
--- a/src/atom_vec_ellipsoid.cpp
+++ b/src/atom_vec_ellipsoid.cpp
@@ -919,7 +919,7 @@ int AtomVecEllipsoid::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   rmass[nlocal] = buf[m++];
   angmom[nlocal][0] = buf[m++];
@@ -1041,7 +1041,7 @@ int AtomVecEllipsoid::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -1094,7 +1094,8 @@ void AtomVecEllipsoid::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -1113,7 +1114,7 @@ void AtomVecEllipsoid::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecEllipsoid::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecEllipsoid::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/atom_vec_ellipsoid.h b/src/atom_vec_ellipsoid.h
index 65966819d6..ef13f6dbd7 100755
--- a/src/atom_vec_ellipsoid.h
+++ b/src/atom_vec_ellipsoid.h
@@ -60,7 +60,7 @@ class AtomVecEllipsoid : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   void data_vel(int, char **);
   int data_vel_hybrid(int, char **);
@@ -76,7 +76,8 @@ class AtomVecEllipsoid : public AtomVec {
   void set_shape(int, double, double, double);
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double *rmass;
   double **angmom,**torque;
diff --git a/src/atom_vec_hybrid.cpp b/src/atom_vec_hybrid.cpp
index fc93450c86..05351cf765 100644
--- a/src/atom_vec_hybrid.cpp
+++ b/src/atom_vec_hybrid.cpp
@@ -803,7 +803,7 @@ void AtomVecHybrid::create_atom(int itype, double *coord)
    grow() occurs here so arrays for all sub-styles are grown
 ------------------------------------------------------------------------- */
 
-void AtomVecHybrid::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecHybrid::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/atom_vec_hybrid.h b/src/atom_vec_hybrid.h
index ea1d1ff234..da9956d695 100644
--- a/src/atom_vec_hybrid.h
+++ b/src/atom_vec_hybrid.h
@@ -53,13 +53,14 @@ class AtomVecHybrid : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **) {return 0;}
   void data_vel(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double **omega,**angmom;
 };
diff --git a/src/atom_vec_line.cpp b/src/atom_vec_line.cpp
index 55997b990b..151d34719d 100644
--- a/src/atom_vec_line.cpp
+++ b/src/atom_vec_line.cpp
@@ -793,7 +793,7 @@ int AtomVecLine::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
   rmass[nlocal] = buf[m++];
@@ -905,7 +905,7 @@ int AtomVecLine::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -952,7 +952,8 @@ void AtomVecLine::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -972,7 +973,7 @@ void AtomVecLine::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecLine::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecLine::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/atom_vec_line.h b/src/atom_vec_line.h
index b37bb66771..b94a63ad3f 100644
--- a/src/atom_vec_line.h
+++ b/src/atom_vec_line.h
@@ -60,7 +60,7 @@ class AtomVecLine : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   void data_vel(int, char **);
   int data_vel_hybrid(int, char **);
@@ -76,7 +76,8 @@ class AtomVecLine : public AtomVec {
   void set_length(int, double);
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   int *molecule;
   double *rmass;
diff --git a/src/atom_vec_sphere.cpp b/src/atom_vec_sphere.cpp
index f77a7e091b..18dffdcab4 100644
--- a/src/atom_vec_sphere.cpp
+++ b/src/atom_vec_sphere.cpp
@@ -794,7 +794,7 @@ int AtomVecSphere::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   radius[nlocal] = buf[m++];
   rmass[nlocal] = buf[m++];
@@ -885,7 +885,7 @@ int AtomVecSphere::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -922,7 +922,8 @@ void AtomVecSphere::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -941,7 +942,7 @@ void AtomVecSphere::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecSphere::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecSphere::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/atom_vec_sphere.h b/src/atom_vec_sphere.h
index 3ee23e9dc4..02ba050b43 100644
--- a/src/atom_vec_sphere.h
+++ b/src/atom_vec_sphere.h
@@ -54,14 +54,15 @@ class AtomVecSphere : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   void data_vel(int, char **);
   int data_vel_hybrid(int, char **);
   bigint memory_usage();
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   double *radius,*density,*rmass;
   double **omega,**torque;
diff --git a/src/atom_vec_tri.cpp b/src/atom_vec_tri.cpp
index 283718ef94..d133951453 100644
--- a/src/atom_vec_tri.cpp
+++ b/src/atom_vec_tri.cpp
@@ -1087,7 +1087,7 @@ int AtomVecTri::unpack_exchange(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
 
   molecule[nlocal] = static_cast<int> (buf[m++]);
   rmass[nlocal] = buf[m++];
@@ -1237,7 +1237,7 @@ int AtomVecTri::unpack_restart(double *buf)
   tag[nlocal] = static_cast<int> (buf[m++]);
   type[nlocal] = static_cast<int> (buf[m++]);
   mask[nlocal] = static_cast<int> (buf[m++]);
-  image[nlocal] = static_cast<int> (buf[m++]);
+  image[nlocal] = static_cast<tagint> (buf[m++]);
   v[nlocal][0] = buf[m++];
   v[nlocal][1] = buf[m++];
   v[nlocal][2] = buf[m++];
@@ -1303,7 +1303,8 @@ void AtomVecTri::create_atom(int itype, double *coord)
   x[nlocal][1] = coord[1];
   x[nlocal][2] = coord[2];
   mask[nlocal] = 1;
-  image[nlocal] = (512 << 20) | (512 << 10) | 512;
+  image[nlocal] = ((tagint) IMGMAX << IMG2BITS) | 
+    ((tagint) IMGMAX << IMGBITS) | IMGMAX;
   v[nlocal][0] = 0.0;
   v[nlocal][1] = 0.0;
   v[nlocal][2] = 0.0;
@@ -1323,7 +1324,7 @@ void AtomVecTri::create_atom(int itype, double *coord)
    initialize other atom quantities
 ------------------------------------------------------------------------- */
 
-void AtomVecTri::data_atom(double *coord, int imagetmp, char **values)
+void AtomVecTri::data_atom(double *coord, tagint imagetmp, char **values)
 {
   int nlocal = atom->nlocal;
   if (nlocal == nmax) grow(0);
diff --git a/src/atom_vec_tri.h b/src/atom_vec_tri.h
index f481c8f072..245c32dde1 100644
--- a/src/atom_vec_tri.h
+++ b/src/atom_vec_tri.h
@@ -62,7 +62,7 @@ class AtomVecTri : public AtomVec {
   int pack_restart(int, double *);
   int unpack_restart(double *);
   void create_atom(int, double *);
-  void data_atom(double *, int, char **);
+  void data_atom(double *, tagint, char **);
   int data_atom_hybrid(int, char **);
   void data_vel(int, char **);
   int data_vel_hybrid(int, char **);
@@ -78,7 +78,8 @@ class AtomVecTri : public AtomVec {
   void set_equilateral(int, double);
 
  private:
-  int *tag,*type,*mask,*image;
+  int *tag,*type,*mask;
+  tagint *image;
   double **x,**v,**f;
   int *molecule;
   double *rmass;
diff --git a/src/change_box.cpp b/src/change_box.cpp
index ddce444e1b..bf1add2bd0 100644
--- a/src/change_box.cpp
+++ b/src/change_box.cpp
@@ -356,7 +356,7 @@ void ChangeBox::command(int narg, char **arg)
   // use irregular() in case box moved a long distance relative to atoms
 
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
   for (i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
 
diff --git a/src/compute_com_molecule.cpp b/src/compute_com_molecule.cpp
index 2b52919f80..80e745f056 100644
--- a/src/compute_com_molecule.cpp
+++ b/src/compute_com_molecule.cpp
@@ -108,7 +108,7 @@ void ComputeCOMMolecule::compute_array()
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -119,9 +119,9 @@ void ComputeCOMMolecule::compute_array()
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       imol = molecule[i];
diff --git a/src/compute_displace_atom.cpp b/src/compute_displace_atom.cpp
index f34e74c91b..b89acd7f56 100644
--- a/src/compute_displace_atom.cpp
+++ b/src/compute_displace_atom.cpp
@@ -104,7 +104,7 @@ void ComputeDisplaceAtom::compute_peratom()
 
   double **x = atom->x;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double *h = domain->h;
@@ -118,9 +118,9 @@ void ComputeDisplaceAtom::compute_peratom()
   if (domain->triclinic == 0) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         dx = x[i][0] + xbox*xprd - xoriginal[i][0];
         dy = x[i][1] + ybox*yprd - xoriginal[i][1];
         dz = x[i][2] + zbox*zprd - xoriginal[i][2];
@@ -134,9 +134,9 @@ void ComputeDisplaceAtom::compute_peratom()
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         dx = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox - xoriginal[i][0];
         dy = x[i][1] + h[1]*ybox + h[3]*zbox - xoriginal[i][1];
         dz = x[i][2] + h[2]*zbox - xoriginal[i][2];
diff --git a/src/compute_gyration.cpp b/src/compute_gyration.cpp
index 551cfc85bb..0cdd07b01d 100644
--- a/src/compute_gyration.cpp
+++ b/src/compute_gyration.cpp
@@ -79,7 +79,7 @@ void ComputeGyration::compute_vector()
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -95,9 +95,9 @@ void ComputeGyration::compute_vector()
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
diff --git a/src/compute_gyration_molecule.cpp b/src/compute_gyration_molecule.cpp
index 412a64e2e7..92c5da07cd 100644
--- a/src/compute_gyration_molecule.cpp
+++ b/src/compute_gyration_molecule.cpp
@@ -136,7 +136,7 @@ void ComputeGyrationMolecule::compute_vector()
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -147,9 +147,9 @@ void ComputeGyrationMolecule::compute_vector()
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       imol = molecule[i];
       if (molmap) imol = molmap[imol-idlo];
       else imol--;
@@ -186,7 +186,7 @@ void ComputeGyrationMolecule::compute_array()
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -197,9 +197,9 @@ void ComputeGyrationMolecule::compute_array()
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       imol = molecule[i];
       if (molmap) imol = molmap[imol-idlo];
       else imol--;
@@ -243,7 +243,7 @@ void ComputeGyrationMolecule::molcom()
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -254,9 +254,9 @@ void ComputeGyrationMolecule::molcom()
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       imol = molecule[i];
diff --git a/src/compute_msd.cpp b/src/compute_msd.cpp
index 9941abe42a..c77da886ba 100644
--- a/src/compute_msd.cpp
+++ b/src/compute_msd.cpp
@@ -133,7 +133,7 @@ void ComputeMSD::compute_vector()
 
   double **x = atom->x;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double *h = domain->h;
@@ -150,9 +150,9 @@ void ComputeMSD::compute_vector()
   if (domain->triclinic == 0) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         dx = x[i][0] + xbox*xprd - cm[0] - xoriginal[i][0];
         dy = x[i][1] + ybox*yprd - cm[1] - xoriginal[i][1];
         dz = x[i][2] + zbox*zprd - cm[2] - xoriginal[i][2];
@@ -165,9 +165,9 @@ void ComputeMSD::compute_vector()
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         dx = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox -
           cm[0] - xoriginal[i][0];
         dy = x[i][1] + h[1]*ybox + h[3]*zbox - cm[1] - xoriginal[i][1];
diff --git a/src/compute_msd_molecule.cpp b/src/compute_msd_molecule.cpp
index bd4e9960fb..c98cca8e1e 100644
--- a/src/compute_msd_molecule.cpp
+++ b/src/compute_msd_molecule.cpp
@@ -125,7 +125,7 @@ void ComputeMSDMolecule::compute_array()
   int *mask = atom->mask;
   int *molecule = atom->molecule;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -136,9 +136,9 @@ void ComputeMSDMolecule::compute_array()
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       if (rmass) massone = rmass[i];
       else massone = mass[type[i]];
       imol = molecule[i];
diff --git a/src/compute_property_atom.cpp b/src/compute_property_atom.cpp
index 4336c890a9..cce33ddb5b 100644
--- a/src/compute_property_atom.cpp
+++ b/src/compute_property_atom.cpp
@@ -623,7 +623,7 @@ void ComputePropertyAtom::pack_zs_triclinic(int n)
 void ComputePropertyAtom::pack_xu(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -631,7 +631,7 @@ void ComputePropertyAtom::pack_xu(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit)
-      buf[n] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
+      buf[n] = x[i][0] + ((image[i] & IMGMASK) - IMGMAX) * xprd;
     else buf[n] = 0.0;
     n += nvalues;
   }
@@ -642,7 +642,7 @@ void ComputePropertyAtom::pack_xu(int n)
 void ComputePropertyAtom::pack_yu(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -650,7 +650,7 @@ void ComputePropertyAtom::pack_yu(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit)
-      buf[n] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
+      buf[n] = x[i][1] + ((image[i] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
     else buf[n] = 0.0;
     n += nvalues;
   }
@@ -661,7 +661,7 @@ void ComputePropertyAtom::pack_yu(int n)
 void ComputePropertyAtom::pack_zu(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -669,7 +669,7 @@ void ComputePropertyAtom::pack_zu(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit)
-      buf[n] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
+      buf[n] = x[i][2] + ((image[i] >> IMG2BITS) - IMGMAX) * zprd;
     else buf[n] = 0.0;
     n += nvalues;
   }
@@ -680,7 +680,7 @@ void ComputePropertyAtom::pack_zu(int n)
 void ComputePropertyAtom::pack_xu_triclinic(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -689,9 +689,9 @@ void ComputePropertyAtom::pack_xu_triclinic(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       buf[n] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
     } else buf[n] = 0.0;
     n += nvalues;
@@ -703,7 +703,7 @@ void ComputePropertyAtom::pack_xu_triclinic(int n)
 void ComputePropertyAtom::pack_yu_triclinic(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -712,8 +712,8 @@ void ComputePropertyAtom::pack_yu_triclinic(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       buf[n] = x[i][1] + h[1]*ybox + h[3]*zbox;
     } else buf[n] = 0.0;
     n += nvalues;
@@ -725,7 +725,7 @@ void ComputePropertyAtom::pack_yu_triclinic(int n)
 void ComputePropertyAtom::pack_zu_triclinic(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -734,7 +734,7 @@ void ComputePropertyAtom::pack_zu_triclinic(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      zbox = (image[i] >> 20) - 512;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       buf[n] = x[i][2] + h[2]*zbox;
     } else buf[n] = 0.0;
     n += nvalues;
@@ -745,12 +745,12 @@ void ComputePropertyAtom::pack_zu_triclinic(int n)
 
 void ComputePropertyAtom::pack_ix(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
-    if (mask[i] & groupbit) buf[n] = (image[i] & 1023) - 512;
+    if (mask[i] & groupbit) buf[n] = (image[i] & IMGMASK) - IMGMAX;
     else buf[n] = 0.0;
     n += nvalues;
   }
@@ -760,12 +760,12 @@ void ComputePropertyAtom::pack_ix(int n)
 
 void ComputePropertyAtom::pack_iy(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
-    if (mask[i] & groupbit) buf[n] = (image[i] >> 10 & 1023) - 512;
+    if (mask[i] & groupbit) buf[n] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
     else buf[n] = 0.0;
     n += nvalues;
   }
@@ -775,12 +775,12 @@ void ComputePropertyAtom::pack_iy(int n)
 
 void ComputePropertyAtom::pack_iz(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
-    if (mask[i] & groupbit) buf[n] = (image[i] >> 20) - 512;
+    if (mask[i] & groupbit) buf[n] = (image[i] >> IMG2BITS) - IMGMAX;
     else buf[n] = 0.0;
     n += nvalues;
   }
diff --git a/src/create_atoms.cpp b/src/create_atoms.cpp
index 347347d266..04e3283e64 100644
--- a/src/create_atoms.cpp
+++ b/src/create_atoms.cpp
@@ -270,7 +270,8 @@ void CreateAtoms::add_single()
   // remap atom if requested
 
   if (remapflag) {
-    int imagetmp = (512 << 20) | (512 << 10) | 512;
+    tagint imagetmp = ((tagint) IMGMAX << IMG2BITS) | 
+      ((tagint) IMGMASK << IMGBITS) | IMGMAX;
     domain->remap(xone,imagetmp);
   }
 
diff --git a/src/displace_atoms.cpp b/src/displace_atoms.cpp
index 8e2a49320e..3fb1a48fda 100644
--- a/src/displace_atoms.cpp
+++ b/src/displace_atoms.cpp
@@ -195,7 +195,7 @@ void DisplaceAtoms::command(int narg, char **arg)
   // use irregular() in case atoms moved a long distance
 
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
   for (i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
 
diff --git a/src/domain.cpp b/src/domain.cpp
index 140f08053e..ebc5e3b4ab 100644
--- a/src/domain.cpp
+++ b/src/domain.cpp
@@ -415,13 +415,14 @@ void Domain::reset_box()
 
 void Domain::pbc()
 {
-  int i,idim,otherdims;
+  int i;
+  tagint idim,otherdims;
   double *lo,*hi,*period;
   int nlocal = atom->nlocal;
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   if (triclinic == 0) {
     lo = boxlo;
@@ -438,20 +439,20 @@ void Domain::pbc()
       if (x[i][0] < lo[0]) {
         x[i][0] += period[0];
         if (deform_vremap && mask[i] & deform_groupbit) v[i][0] += h_rate[0];
-        idim = image[i] & 1023;
+        idim = image[i] & IMGMASK;
         otherdims = image[i] ^ idim;
         idim--;
-        idim &= 1023;
+        idim &= IMGMASK;
         image[i] = otherdims | idim;
       }
       if (x[i][0] >= hi[0]) {
         x[i][0] -= period[0];
         x[i][0] = MAX(x[i][0],lo[0]);
         if (deform_vremap && mask[i] & deform_groupbit) v[i][0] -= h_rate[0];
-        idim = image[i] & 1023;
+        idim = image[i] & IMGMASK;
         otherdims = image[i] ^ idim;
         idim++;
-        idim &= 1023;
+        idim &= IMGMASK;
         image[i] = otherdims | idim;
       }
     }
@@ -463,11 +464,11 @@ void Domain::pbc()
           v[i][0] += h_rate[5];
           v[i][1] += h_rate[1];
         }
-        idim = (image[i] >> 10) & 1023;
-        otherdims = image[i] ^ (idim << 10);
+        idim = (image[i] >> IMGBITS) & IMGMASK;
+        otherdims = image[i] ^ (idim << IMGBITS);
         idim--;
-        idim &= 1023;
-        image[i] = otherdims | (idim << 10);
+        idim &= IMGMASK;
+        image[i] = otherdims | (idim << IMGBITS);
       }
       if (x[i][1] >= hi[1]) {
         x[i][1] -= period[1];
@@ -476,11 +477,11 @@ void Domain::pbc()
           v[i][0] -= h_rate[5];
           v[i][1] -= h_rate[1];
         }
-        idim = (image[i] >> 10) & 1023;
-        otherdims = image[i] ^ (idim << 10);
+        idim = (image[i] >> IMGBITS) & IMGMASK;
+        otherdims = image[i] ^ (idim << IMGBITS);
         idim++;
-        idim &= 1023;
-        image[i] = otherdims | (idim << 10);
+        idim &= IMGMASK;
+        image[i] = otherdims | (idim << IMGBITS);
       }
     }
 
@@ -492,11 +493,11 @@ void Domain::pbc()
           v[i][1] += h_rate[3];
           v[i][2] += h_rate[2];
         }
-        idim = image[i] >> 20;
-        otherdims = image[i] ^ (idim << 20);
+        idim = image[i] >> IMG2BITS;
+        otherdims = image[i] ^ (idim << IMG2BITS);
         idim--;
-        idim &= 1023;
-        image[i] = otherdims | (idim << 20);
+        idim &= IMGMASK;
+        image[i] = otherdims | (idim << IMG2BITS);
       }
       if (x[i][2] >= hi[2]) {
         x[i][2] -= period[2];
@@ -506,11 +507,11 @@ void Domain::pbc()
           v[i][1] -= h_rate[3];
           v[i][2] -= h_rate[2];
         }
-        idim = image[i] >> 20;
-        otherdims = image[i] ^ (idim << 20);
+        idim = image[i] >> IMG2BITS;
+        otherdims = image[i] ^ (idim << IMG2BITS);
         idim++;
-        idim &= 1023;
-        image[i] = otherdims | (idim << 20);
+        idim &= IMGMASK;
+        image[i] = otherdims | (idim << IMG2BITS);
       }
     }
   }
@@ -852,10 +853,11 @@ void Domain::closest_image(const double * const xi, const double * const xj,
    increment/decrement in wrap-around fashion
 ------------------------------------------------------------------------- */
 
-void Domain::remap(double *x, int &image)
+void Domain::remap(double *x, tagint &image)
 {
   double *lo,*hi,*period,*coord;
   double lamda[3];
+  tagint idim,otherdims;
 
   if (triclinic == 0) {
     lo = boxlo;
@@ -873,18 +875,18 @@ void Domain::remap(double *x, int &image)
   if (xperiodic) {
     while (coord[0] < lo[0]) {
       coord[0] += period[0];
-      int idim = image & 1023;
-      int otherdims = image ^ idim;
+      idim = image & IMGMASK;
+      otherdims = image ^ idim;
       idim--;
-      idim &= 1023;
+      idim &= IMGMASK;
       image = otherdims | idim;
     }
     while (coord[0] >= hi[0]) {
       coord[0] -= period[0];
-      int idim = image & 1023;
-      int otherdims = image ^ idim;
+      idim = image & IMGMASK;
+      otherdims = image ^ idim;
       idim++;
-      idim &= 1023;
+      idim &= IMGMASK;
       image = otherdims | idim;
     }
     coord[0] = MAX(coord[0],lo[0]);
@@ -893,19 +895,19 @@ void Domain::remap(double *x, int &image)
   if (yperiodic) {
     while (coord[1] < lo[1]) {
       coord[1] += period[1];
-      int idim = (image >> 10) & 1023;
-      int otherdims = image ^ (idim << 10);
+      idim = (image >> IMGBITS) & IMGMASK;
+      otherdims = image ^ (idim << IMGBITS);
       idim--;
-      idim &= 1023;
-      image = otherdims | (idim << 10);
+      idim &= IMGMASK;
+      image = otherdims | (idim << IMGBITS);
     }
     while (coord[1] >= hi[1]) {
       coord[1] -= period[1];
-      int idim = (image >> 10) & 1023;
-      int otherdims = image ^ (idim << 10);
+      idim = (image >> IMGBITS) & IMGMASK;
+      otherdims = image ^ (idim << IMGBITS);
       idim++;
-      idim &= 1023;
-      image = otherdims | (idim << 10);
+      idim &= IMGMASK;
+      image = otherdims | (idim << IMGBITS);
     }
     coord[1] = MAX(coord[1],lo[1]);
   }
@@ -913,19 +915,19 @@ void Domain::remap(double *x, int &image)
   if (zperiodic) {
     while (coord[2] < lo[2]) {
       coord[2] += period[2];
-      int idim = image >> 20;
-      int otherdims = image ^ (idim << 20);
+      idim = image >> IMG2BITS;
+      otherdims = image ^ (idim << IMG2BITS);
       idim--;
-      idim &= 1023;
-      image = otherdims | (idim << 20);
+      idim &= IMGMASK;
+      image = otherdims | (idim << IMG2BITS);
     }
     while (coord[2] >= hi[2]) {
       coord[2] -= period[2];
-      int idim = image >> 20;
-      int otherdims = image ^ (idim << 20);
+      idim = image >> IMG2BITS;
+      otherdims = image ^ (idim << IMG2BITS);
       idim++;
-      idim &= 1023;
-      image = otherdims | (idim << 20);
+      idim &= IMGMASK;
+      image = otherdims | (idim << IMG2BITS);
     }
     coord[2] = MAX(coord[2],lo[2]);
   }
@@ -1063,11 +1065,11 @@ void Domain::remap_near(double *xnew, double *xold)
    for triclinic, use h[] to add in tilt factors in other dims as needed
 ------------------------------------------------------------------------- */
 
-void Domain::unmap(double *x, int image)
+void Domain::unmap(double *x, tagint image)
 {
-  int xbox = (image & 1023) - 512;
-  int ybox = (image >> 10 & 1023) - 512;
-  int zbox = (image >> 20) - 512;
+  int xbox = (image & IMGMASK) - IMGMAX;
+  int ybox = (image >> IMGBITS & IMGMASK) - IMGMAX;
+  int zbox = (image >> IMG2BITS) - IMGMAX;
 
   if (triclinic == 0) {
     x[0] += xbox*xprd;
@@ -1086,11 +1088,11 @@ void Domain::unmap(double *x, int image)
    for triclinic, use h[] to add in tilt factors in other dims as needed
 ------------------------------------------------------------------------- */
 
-void Domain::unmap(double *x, int image, double *y)
+void Domain::unmap(double *x, tagint image, double *y)
 {
-  int xbox = (image & 1023) - 512;
-  int ybox = (image >> 10 & 1023) - 512;
-  int zbox = (image >> 20) - 512;
+  int xbox = (image & IMGMASK) - IMGMAX;
+  int ybox = (image >> IMGBITS & IMGMASK) - IMGMAX;
+  int zbox = (image >> IMG2BITS) - IMGMAX;
 
   if (triclinic == 0) {
     y[0] = x[0] + xbox*xprd;
@@ -1124,19 +1126,20 @@ void Domain::unmap(double *x, int image, double *y)
 
 void Domain::image_flip(int m, int n, int p)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
-    int xbox = (image[i] & 1023) - 512;
-    int ybox = (image[i] >> 10 & 1023) - 512;
-    int zbox = (image[i] >> 20) - 512;
+    int xbox = (image[i] & IMGMASK) - IMGMAX;
+    int ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    int zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     ybox -= p*zbox;
     xbox -= m*ybox + n*zbox;
 
-    image[i] = ((zbox + 512 & 1023) << 20) |
-      ((ybox + 512 & 1023) << 10) | (xbox + 512 & 1023);
+    image[i] = ((zbox + (tagint) IMGMAX & IMGMASK) << IMG2BITS) |
+      ((ybox + (tagint) IMGMAX & IMGMASK) << IMGBITS) | 
+      (xbox + IMGMAX & IMGMASK);
   }
 }
 
diff --git a/src/domain.h b/src/domain.h
index 13cd6a44c2..457174b1f8 100644
--- a/src/domain.h
+++ b/src/domain.h
@@ -100,11 +100,11 @@ class Domain : protected Pointers {
   int closest_image(int, int);
   void closest_image(const double * const, const double * const,
                      double * const);
-  void remap(double *, int &);
+  void remap(double *, tagint &);
   void remap(double *);
   void remap_near(double *, double *);
-  void unmap(double *, int);
-  void unmap(double *, int, double *);
+  void unmap(double *, tagint);
+  void unmap(double *, tagint, double *);
   void image_flip(int, int, int);
   void set_lattice(int, char **);
   void add_region(int, char **);
diff --git a/src/dump_atom.cpp b/src/dump_atom.cpp
index 42ddf8f196..5641b4ea53 100644
--- a/src/dump_atom.cpp
+++ b/src/dump_atom.cpp
@@ -230,7 +230,7 @@ void DumpAtom::pack_scale_image(int *ids)
 
   int *tag = atom->tag;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
@@ -247,9 +247,9 @@ void DumpAtom::pack_scale_image(int *ids)
       buf[m++] = (x[i][0] - boxxlo) * invxprd;
       buf[m++] = (x[i][1] - boxylo) * invyprd;
       buf[m++] = (x[i][2] - boxzlo) * invzprd;
-      buf[m++] = (image[i] & 1023) - 512;
-      buf[m++] = (image[i] >> 10 & 1023) - 512;
-      buf[m++] = (image[i] >> 20) - 512;
+      buf[m++] = (image[i] & IMGMASK) - IMGMAX;
+      buf[m++] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      buf[m++] = (image[i] >> IMG2BITS) - IMGMAX;
       if (ids) ids[n++] = tag[i];
     }
 }
@@ -290,7 +290,7 @@ void DumpAtom::pack_scale_image_triclinic(int *ids)
 
   int *tag = atom->tag;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
@@ -306,9 +306,9 @@ void DumpAtom::pack_scale_image_triclinic(int *ids)
       buf[m++] = lamda[0];
       buf[m++] = lamda[1];
       buf[m++] = lamda[2];
-      buf[m++] = (image[i] & 1023) - 512;
-      buf[m++] = (image[i] >> 10 & 1023) - 512;
-      buf[m++] = (image[i] >> 20) - 512;
+      buf[m++] = (image[i] & IMGMASK) - IMGMAX;
+      buf[m++] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      buf[m++] = (image[i] >> IMG2BITS) - IMGMAX;
       if (ids) ids[n++] = tag[i];
     }
 }
@@ -348,7 +348,7 @@ void DumpAtom::pack_noscale_image(int *ids)
 
   int *tag = atom->tag;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   double **x = atom->x;
   int nlocal = atom->nlocal;
@@ -361,9 +361,9 @@ void DumpAtom::pack_noscale_image(int *ids)
       buf[m++] = x[i][0];
       buf[m++] = x[i][1];
       buf[m++] = x[i][2];
-      buf[m++] = (image[i] & 1023) - 512;
-      buf[m++] = (image[i] >> 10 & 1023) - 512;
-      buf[m++] = (image[i] >> 20) - 512;
+      buf[m++] = (image[i] & IMGMASK) - IMGMAX;
+      buf[m++] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      buf[m++] = (image[i] >> IMG2BITS) - IMGMAX;
       if (ids) ids[n++] = tag[i];
     }
 }
diff --git a/src/dump_custom.cpp b/src/dump_custom.cpp
index 32c51d5e34..5c5c951ee7 100644
--- a/src/dump_custom.cpp
+++ b/src/dump_custom.cpp
@@ -532,61 +532,61 @@ int DumpCustom::count()
 
       } else if (thresh_array[ithresh] == XU) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double xprd = domain->xprd;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
+          dchoose[i] = x[i][0] + ((image[i] & IMGMASK) - IMGMAX) * xprd;
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == YU) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double yprd = domain->yprd;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
+          dchoose[i] = x[i][1] + ((image[i] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == ZU) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double zprd = domain->zprd;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
+          dchoose[i] = x[i][2] + ((image[i] >> IMG2BITS) - IMGMAX) * zprd;
         ptr = dchoose;
         nstride = 1;
 
       } else if (thresh_array[ithresh] == XUTRI) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double *h = domain->h;
         int xbox,ybox,zbox;
         for (i = 0; i < nlocal; i++) {
-          xbox = (image[i] & 1023) - 512;
-          ybox = (image[i] >> 10 & 1023) - 512;
-          zbox = (image[i] >> 20) - 512;
+          xbox = (image[i] & IMGMASK) - IMGMAX;
+          ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+          zbox = (image[i] >> IMG2BITS) - IMGMAX;
           dchoose[i] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
         }
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == YUTRI) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double *h = domain->h;
         int ybox,zbox;
         for (i = 0; i < nlocal; i++) {
-          ybox = (image[i] >> 10 & 1023) - 512;
-          zbox = (image[i] >> 20) - 512;
+          ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+          zbox = (image[i] >> IMG2BITS) - IMGMAX;
           dchoose[i] = x[i][1] + h[1]*ybox + h[3]*zbox;
         }
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == ZUTRI) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double *h = domain->h;
         int zbox;
         for (i = 0; i < nlocal; i++) {
-          zbox = (image[i] >> 20) - 512;
+          zbox = (image[i] >> IMG2BITS) - IMGMAX;
           dchoose[i] = x[i][2] + h[2]*zbox;
         }
         ptr = dchoose;
@@ -594,85 +594,85 @@ int DumpCustom::count()
 
       } else if (thresh_array[ithresh] == XSU) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double boxxlo = domain->boxlo[0];
         double invxprd = 1.0/domain->xprd;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = (x[i][0] - boxxlo) * invxprd + (image[i] & 1023) - 512;
+          dchoose[i] = (x[i][0] - boxxlo) * invxprd + (image[i] & IMGMASK) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
 
       } else if (thresh_array[ithresh] == YSU) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double boxylo = domain->boxlo[1];
         double invyprd = 1.0/domain->yprd;
         for (i = 0; i < nlocal; i++)
           dchoose[i] =
-            (x[i][1] - boxylo) * invyprd + (image[i] >> 10 & 1023) - 512;
+            (x[i][1] - boxylo) * invyprd + (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
 
       } else if (thresh_array[ithresh] == ZSU) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double boxzlo = domain->boxlo[2];
         double invzprd = 1.0/domain->zprd;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = (x[i][2] - boxzlo) * invzprd + (image[i] >> 20) - 512;
+          dchoose[i] = (x[i][2] - boxzlo) * invzprd + (image[i] >> IMG2BITS) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
 
       } else if (thresh_array[ithresh] == XSUTRI) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double *boxlo = domain->boxlo;
         double *h_inv = domain->h_inv;
         for (i = 0; i < nlocal; i++)
           dchoose[i] = h_inv[0]*(x[i][0]-boxlo[0]) +
             h_inv[5]*(x[i][1]-boxlo[1]) +
             h_inv[4]*(x[i][2]-boxlo[2]) +
-            (image[i] & 1023) - 512;
+            (image[i] & IMGMASK) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == YSUTRI) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double *boxlo = domain->boxlo;
         double *h_inv = domain->h_inv;
         for (i = 0; i < nlocal; i++)
           dchoose[i] = h_inv[1]*(x[i][1]-boxlo[1]) +
             h_inv[3]*(x[i][2]-boxlo[2]) +
-            (image[i] >> 10 & 1023) - 512;
+            (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == ZSUTRI) {
         double **x = atom->x;
-        int *image = atom->image;
+        tagint *image = atom->image;
         double *boxlo = domain->boxlo;
         double *h_inv = domain->h_inv;
         for (i = 0; i < nlocal; i++)
           dchoose[i] = h_inv[2]*(x[i][2]-boxlo[2]) +
-            (image[i] >> 20) - 512;
+            (image[i] >> IMG2BITS) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
 
       } else if (thresh_array[ithresh] == IX) {
-        int *image = atom->image;
+        tagint *image = atom->image;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = (image[i] & 1023) - 512;
+          dchoose[i] = (image[i] & IMGMASK) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == IY) {
-        int *image = atom->image;
+        tagint *image = atom->image;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = (image[i] >> 10 & 1023) - 512;
+          dchoose[i] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
       } else if (thresh_array[ithresh] == IZ) {
-        int *image = atom->image;
+        tagint *image = atom->image;
         for (i = 0; i < nlocal; i++)
-          dchoose[i] = (image[i] >> 20) - 512;
+          dchoose[i] = (image[i] >> IMG2BITS) - IMGMAX;
         ptr = dchoose;
         nstride = 1;
 
@@ -1847,13 +1847,13 @@ void DumpCustom::pack_xu(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double xprd = domain->xprd;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    buf[n] = x[j][0] + ((image[j] & 1023) - 512) * xprd;
+    buf[n] = x[j][0] + ((image[j] & IMGMASK) - IMGMAX) * xprd;
     n += size_one;
   }
 }
@@ -1864,13 +1864,13 @@ void DumpCustom::pack_yu(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double yprd = domain->yprd;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    buf[n] = x[j][1] + ((image[j] >> 10 & 1023) - 512) * yprd;
+    buf[n] = x[j][1] + ((image[j] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
     n += size_one;
   }
 }
@@ -1881,13 +1881,13 @@ void DumpCustom::pack_zu(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double zprd = domain->zprd;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    buf[n] = x[j][2] + ((image[j] >> 20) - 512) * zprd;
+    buf[n] = x[j][2] + ((image[j] >> IMG2BITS) - IMGMAX) * zprd;
     n += size_one;
   }
 }
@@ -1898,16 +1898,16 @@ void DumpCustom::pack_xu_triclinic(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double *h = domain->h;
   int xbox,ybox,zbox;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    xbox = (image[j] & 1023) - 512;
-    ybox = (image[j] >> 10 & 1023) - 512;
-    zbox = (image[j] >> 20) - 512;
+    xbox = (image[j] & IMGMASK) - IMGMAX;
+    ybox = (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[j] >> IMG2BITS) - IMGMAX;
     buf[n] = x[j][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
     n += size_one;
   }
@@ -1919,15 +1919,15 @@ void DumpCustom::pack_yu_triclinic(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double *h = domain->h;
   int ybox,zbox;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    ybox = (image[j] >> 10 & 1023) - 512;
-    zbox = (image[j] >> 20) - 512;
+    ybox = (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[j] >> IMG2BITS) - IMGMAX;
     buf[n] = x[j][1] + h[1]*ybox + h[3]*zbox;
     n += size_one;
   }
@@ -1939,14 +1939,14 @@ void DumpCustom::pack_zu_triclinic(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double *h = domain->h;
   int zbox;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    zbox = (image[j] >> 20) - 512;
+    zbox = (image[j] >> IMG2BITS) - IMGMAX;
     buf[n] = x[j][2] + h[2]*zbox;
     n += size_one;
   }
@@ -1958,14 +1958,14 @@ void DumpCustom::pack_xsu(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double boxxlo = domain->boxlo[0];
   double invxprd = 1.0/domain->xprd;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    buf[n] = (x[j][0] - boxxlo) * invxprd + (image[j] & 1023) - 512;
+    buf[n] = (x[j][0] - boxxlo) * invxprd + (image[j] & IMGMASK) - IMGMAX;
     n += size_one;
   }
 }
@@ -1976,14 +1976,14 @@ void DumpCustom::pack_ysu(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double boxylo = domain->boxlo[1];
   double invyprd = 1.0/domain->yprd;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    buf[n] = (x[j][1] - boxylo) * invyprd + (image[j] >> 10 & 1023) - 512;
+    buf[n] = (x[j][1] - boxylo) * invyprd + (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
     n += size_one;
   }
 }
@@ -1994,14 +1994,14 @@ void DumpCustom::pack_zsu(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double boxzlo = domain->boxlo[2];
   double invzprd = 1.0/domain->zprd;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    buf[n] = (x[j][2] - boxzlo) * invzprd + (image[j] >> 20) - 512;
+    buf[n] = (x[j][2] - boxzlo) * invzprd + (image[j] >> IMG2BITS) - IMGMAX;
     n += size_one;
   }
 }
@@ -2012,7 +2012,7 @@ void DumpCustom::pack_xsu_triclinic(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double *boxlo = domain->boxlo;
   double *h_inv = domain->h_inv;
@@ -2020,7 +2020,7 @@ void DumpCustom::pack_xsu_triclinic(int n)
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
     buf[n] = h_inv[0]*(x[j][0]-boxlo[0]) + h_inv[5]*(x[j][1]-boxlo[1]) +
-      h_inv[4]*(x[j][2]-boxlo[2]) + (image[j] & 1023) - 512;
+      h_inv[4]*(x[j][2]-boxlo[2]) + (image[j] & IMGMASK) - IMGMAX;
     n += size_one;
   }
 }
@@ -2031,7 +2031,7 @@ void DumpCustom::pack_ysu_triclinic(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double *boxlo = domain->boxlo;
   double *h_inv = domain->h_inv;
@@ -2039,7 +2039,7 @@ void DumpCustom::pack_ysu_triclinic(int n)
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
     buf[n] = h_inv[1]*(x[j][1]-boxlo[1]) + h_inv[3]*(x[j][2]-boxlo[2]) +
-      (image[j] >> 10 & 1023) - 512;
+      (image[j] >> IMGBITS & IMGMASK) - IMGMAX;
     n += size_one;
   }
 }
@@ -2050,14 +2050,14 @@ void DumpCustom::pack_zsu_triclinic(int n)
 {
   int j;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   double *boxlo = domain->boxlo;
   double *h_inv = domain->h_inv;
 
   for (int i = 0; i < nchoose; i++) {
     j = clist[i];
-    buf[n] = h_inv[2]*(x[j][2]-boxlo[2]) + (image[j] >> 20) - 512;
+    buf[n] = h_inv[2]*(x[j][2]-boxlo[2]) + (image[j] >> IMG2BITS) - IMGMAX;
     n += size_one;
   }
 }
@@ -2066,10 +2066,10 @@ void DumpCustom::pack_zsu_triclinic(int n)
 
 void DumpCustom::pack_ix(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   for (int i = 0; i < nchoose; i++) {
-    buf[n] = (image[clist[i]] & 1023) - 512;
+    buf[n] = (image[clist[i]] & IMGMASK) - IMGMAX;
     n += size_one;
   }
 }
@@ -2078,10 +2078,10 @@ void DumpCustom::pack_ix(int n)
 
 void DumpCustom::pack_iy(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   for (int i = 0; i < nchoose; i++) {
-    buf[n] = (image[clist[i]] >> 10 & 1023) - 512;
+    buf[n] = (image[clist[i]] >> IMGBITS & IMGMASK) - IMGMAX;
     n += size_one;
   }
 }
@@ -2090,10 +2090,10 @@ void DumpCustom::pack_iy(int n)
 
 void DumpCustom::pack_iz(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   for (int i = 0; i < nchoose; i++) {
-    buf[n] = (image[clist[i]] >> 20) - 512;
+    buf[n] = (image[clist[i]] >> IMG2BITS) - IMGMAX;
     n += size_one;
   }
 }
diff --git a/src/dump_dcd.cpp b/src/dump_dcd.cpp
index a758f1a6e8..ca08a1da0e 100644
--- a/src/dump_dcd.cpp
+++ b/src/dump_dcd.cpp
@@ -180,7 +180,7 @@ void DumpDCD::pack(int *ids)
 
   int *tag = atom->tag;
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -195,9 +195,9 @@ void DumpDCD::pack(int *ids)
 
     for (int i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
-        int ix = (image[i] & 1023) - 512;
-        int iy = (image[i] >> 10 & 1023) - 512;
-        int iz = (image[i] >> 20) - 512;
+        int ix = (image[i] & IMGMASK) - IMGMAX;
+        int iy = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        int iz = (image[i] >> IMG2BITS) - IMGMAX;
 
         if (domain->triclinic) {
           buf[m++] = x[i][0] + ix * xprd + iy * xy + iz * xz;
diff --git a/src/fix_addforce.cpp b/src/fix_addforce.cpp
index cb1e7ca1aa..2523c7cc05 100644
--- a/src/fix_addforce.cpp
+++ b/src/fix_addforce.cpp
@@ -226,7 +226,7 @@ void FixAddForce::post_force(int vflag)
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   // reallocate sforce array if necessary
@@ -253,9 +253,9 @@ void FixAddForce::post_force(int vflag)
             !domain->regions[iregion]->match(x[i][0],x[i][1],x[i][2]))
           continue;
 
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         foriginal[0] -= xvalue * (x[i][0]+xbox*xprd) +
           yvalue * (x[i][1]+ybox*yprd) + zvalue * (x[i][2]+zbox*zprd);
 
diff --git a/src/fix_deform.cpp b/src/fix_deform.cpp
index 56a24723d2..d972d0057e 100644
--- a/src/fix_deform.cpp
+++ b/src/fix_deform.cpp
@@ -656,7 +656,7 @@ void FixDeform::pre_exchange()
   domain->image_flip(flipxy,flipxz,flipyz);
 
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
   for (int i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
 
diff --git a/src/fix_momentum.cpp b/src/fix_momentum.cpp
index 590a55dbc0..69e06aeaed 100644
--- a/src/fix_momentum.cpp
+++ b/src/fix_momentum.cpp
@@ -118,7 +118,7 @@ void FixMomentum::end_of_step()
     double **x = atom->x;
     double **v = atom->v;
     int *mask = atom->mask;
-    int *image = atom->image;
+    tagint *image = atom->image;
     int nlocal = atom->nlocal;
 
     int xbox,ybox,zbox;
@@ -129,9 +129,9 @@ void FixMomentum::end_of_step()
 
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         dx = (x[i][0] + xbox*xprd) - xcm[0];
         dy = (x[i][1] + ybox*yprd) - xcm[1];
         dz = (x[i][2] + zbox*zprd) - xcm[2];
diff --git a/src/fix_move.cpp b/src/fix_move.cpp
index 0740fdf4fe..d1bc5456e0 100644
--- a/src/fix_move.cpp
+++ b/src/fix_move.cpp
@@ -251,7 +251,7 @@ FixMove::FixMove(LAMMPS *lmp, int narg, char **arg) :
   // xoriginal = initial unwrapped positions of atoms
 
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -870,7 +870,7 @@ void FixMove::copy_arrays(int i, int j)
 void FixMove::set_arrays(int i)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
 
   // particle not in group
diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp
index 6548045ff4..64a3932327 100644
--- a/src/fix_nh.cpp
+++ b/src/fix_nh.cpp
@@ -2246,7 +2246,7 @@ void FixNH::pre_exchange()
     domain->image_flip(flipxy,flipxz,flipyz);
 
     double **x = atom->x;
-    int *image = atom->image;
+    tagint *image = atom->image;
     int nlocal = atom->nlocal;
     for (int i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
 
diff --git a/src/fix_orient_fcc.cpp b/src/fix_orient_fcc.cpp
index 5f8193c10f..d1ba81bf87 100644
--- a/src/fix_orient_fcc.cpp
+++ b/src/fix_orient_fcc.cpp
@@ -90,14 +90,14 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) :
   // read xi and chi reference orientations from files
 
   if (me == 0) {
-    char line[512];
+    char line[IMGMAX];
     char *result;
     int count;
 
     FILE *infile = fopen(xifilename,"r");
     if (infile == NULL) error->one(FLERR,"Fix orient/fcc file open failed");
     for (int i = 0; i < 6; i++) {
-      result = fgets(line,512,infile);
+      result = fgets(line,IMGMAX,infile);
       if (!result) error->one(FLERR,"Fix orient/fcc file read failed");
       count = sscanf(line,"%lg %lg %lg",&Rxi[i][0],&Rxi[i][1],&Rxi[i][2]);
       if (count != 3) error->one(FLERR,"Fix orient/fcc file read failed");
@@ -107,7 +107,7 @@ FixOrientFCC::FixOrientFCC(LAMMPS *lmp, int narg, char **arg) :
     infile = fopen(chifilename,"r");
     if (infile == NULL) error->one(FLERR,"Fix orient/fcc file open failed");
     for (int i = 0; i < 6; i++) {
-      result = fgets(line,512,infile);
+      result = fgets(line,IMGMAX,infile);
       if (!result) error->one(FLERR,"Fix orient/fcc file read failed");
       count = sscanf(line,"%lg %lg %lg",&Rchi[i][0],&Rchi[i][1],&Rchi[i][2]);
       if (count != 3) error->one(FLERR,"Fix orient/fcc file read failed");
diff --git a/src/fix_rigid.cpp b/src/fix_rigid.cpp
index 6de2d0ed7b..1a5afbb37b 100644
--- a/src/fix_rigid.cpp
+++ b/src/fix_rigid.cpp
@@ -601,7 +601,7 @@ void FixRigid::setup(int vflag)
   // angmom = angular momentum of each rigid body
   // torque = torque on each rigid body
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
 
   double xprd = domain->xprd;
@@ -620,9 +620,9 @@ void FixRigid::setup(int vflag)
     if (body[i] < 0) continue;
     ibody = body[i];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     if (triclinic == 0) {
       xunwrap = x[i][0] + xbox*xprd;
@@ -833,7 +833,7 @@ void FixRigid::final_integrate()
 
   // sum over atoms to get force and torque on rigid body
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
   double **f = atom->f;
   int nlocal = atom->nlocal;
@@ -860,9 +860,9 @@ void FixRigid::final_integrate()
     sum[ibody][1] += f[i][1];
     sum[ibody][2] += f[i][2];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     if (triclinic == 0) {
       xunwrap = x[i][0] + xbox*xprd;
@@ -1021,7 +1021,7 @@ void FixRigid::final_integrate_respa(int ilevel, int iloop)
 
 void FixRigid::pre_neighbor()
 {
-  int original,oldimage,newimage;
+  tagint original,oldimage,newimage;
 
   for (int ibody = 0; ibody < nbody; ibody++) {
     original = imagebody[ibody];
@@ -1029,14 +1029,14 @@ void FixRigid::pre_neighbor()
 
     if (original == imagebody[ibody]) remapflag[ibody][3] = 0;
     else {
-      oldimage = original & 1023;
-      newimage = imagebody[ibody] & 1023;
+      oldimage = original & IMGMASK;
+      newimage = imagebody[ibody] & IMGMASK;
       remapflag[ibody][0] = newimage - oldimage;
-      oldimage = (original >> 10) & 1023;
-      newimage = (imagebody[ibody] >> 10) & 1023;
+      oldimage = (original >> IMGBITS) & IMGMASK;
+      newimage = (imagebody[ibody] >> IMGBITS) & IMGMASK;
       remapflag[ibody][1] = newimage - oldimage;
-      oldimage = original >> 20;
-      newimage = imagebody[ibody] >> 20;
+      oldimage = original >> IMG2BITS;
+      newimage = imagebody[ibody] >> IMG2BITS;
       remapflag[ibody][2] = newimage - oldimage;
       remapflag[ibody][3] = 1;
     }
@@ -1044,10 +1044,11 @@ void FixRigid::pre_neighbor()
 
   // adjust image flags of any atom in a rigid body whose xcm was remapped
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
-  int ibody,idim,otherdims;
+  int ibody;
+  tagint idim,otherdims;
 
   for (int i = 0; i < nlocal; i++) {
     if (body[i] == -1) continue;
@@ -1055,25 +1056,25 @@ void FixRigid::pre_neighbor()
     ibody = body[i];
 
     if (remapflag[ibody][0]) {
-      idim = image[i] & 1023;
+      idim = image[i] & IMGMASK;
       otherdims = image[i] ^ idim;
       idim -= remapflag[ibody][0];
-      idim &= 1023;
+      idim &= IMGMASK;
       image[i] = otherdims | idim;
     }
     if (remapflag[ibody][1]) {
-      idim = (image[i] >> 10) & 1023;
-      otherdims = image[i] ^ (idim << 10);
+      idim = (image[i] >> IMGBITS) & IMGMASK;
+      otherdims = image[i] ^ (idim << IMGBITS);
       idim -= remapflag[ibody][1];
-      idim &= 1023;
-      image[i] = otherdims | (idim << 10);
+      idim &= IMGMASK;
+      image[i] = otherdims | (idim << IMGBITS);
     }
     if (remapflag[ibody][2]) {
-      idim = image[i] >> 20;
-      otherdims = image[i] ^ (idim << 20);
+      idim = image[i] >> IMG2BITS;
+      otherdims = image[i] ^ (idim << IMG2BITS);
       idim -= remapflag[ibody][2];
-      idim &= 1023;
-      image[i] = otherdims | (idim << 20);
+      idim &= IMGMASK;
+      image[i] = otherdims | (idim << IMG2BITS);
     }
   }
 }
@@ -1183,7 +1184,7 @@ void FixRigid::set_xv()
   double xy,xz,yz;
   double ione[3],exone[3],eyone[3],ezone[3],vr[6],p[3][3];
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
   double **v = atom->v;
   double **f = atom->f;
@@ -1208,9 +1209,9 @@ void FixRigid::set_xv()
     if (body[i] < 0) continue;
     ibody = body[i];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     // save old positions and velocities for virial
 
@@ -1367,7 +1368,7 @@ void FixRigid::set_v()
   double *rmass = atom->rmass;
   double *mass = atom->mass;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double xprd = domain->xprd;
@@ -1416,9 +1417,9 @@ void FixRigid::set_v()
       fc1 = massone*(v[i][1] - v1)/dtf - f[i][1];
       fc2 = massone*(v[i][2] - v2)/dtf - f[i][2];
 
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
       if (triclinic == 0) {
         x0 = x[i][0] + xbox*xprd;
@@ -1581,7 +1582,7 @@ void FixRigid::setup_bodies()
   // error if image flag is not 0 in a non-periodic dim
 
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
 
   int *periodicity = domain->periodicity;
   double xprd = domain->xprd;
@@ -1600,9 +1601,9 @@ void FixRigid::setup_bodies()
     if (body[i] < 0) continue;
     ibody = body[i];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
     if (rmass) massone = rmass[i];
     else massone = mass[type[i]];
 
@@ -1650,7 +1651,8 @@ void FixRigid::setup_bodies()
   // then remap the xcm of each body back into simulation box if needed
 
   for (ibody = 0; ibody < nbody; ibody++)
-    imagebody[ibody] = (512 << 20) | (512 << 10) | 512;
+    imagebody[ibody] = ((tagint) IMGMAX << IMG2BITS) | 
+      ((tagint) IMGMASK << IMGBITS) | IMGMAX;
 
   pre_neighbor();
 
@@ -1667,9 +1669,9 @@ void FixRigid::setup_bodies()
     if (body[i] < 0) continue;
     ibody = body[i];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     if (triclinic == 0) {
       xunwrap = x[i][0] + xbox*xprd;
@@ -1822,9 +1824,9 @@ void FixRigid::setup_bodies()
 
     ibody = body[i];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     if (triclinic == 0) {
       xunwrap = x[i][0] + xbox*xprd;
@@ -2287,7 +2289,7 @@ double FixRigid::compute_array(int i, int j)
   if (j < 6) return vcm[i][j-3];
   if (j < 9) return fcm[i][j-6];
   if (j < 12) return torque[i][j-9];
-  if (j == 12) return (imagebody[i] & 1023) - 512;
-  if (j == 13) return (imagebody[i] >> 10 & 1023) - 512;
-  return (imagebody[i] >> 20) - 512;
+  if (j == 12) return (imagebody[i] & IMGMASK) - IMGMAX;
+  if (j == 13) return (imagebody[i] >> IMGBITS & IMGMASK) - IMGMAX;
+  return (imagebody[i] >> IMG2BITS) - IMGMAX;
 }
diff --git a/src/fix_rigid.h b/src/fix_rigid.h
index 26cfbf7522..050cb92672 100644
--- a/src/fix_rigid.h
+++ b/src/fix_rigid.h
@@ -82,7 +82,7 @@ class FixRigid : public Fix {
   double **omega;           // angular velocity of each in space coords
   double **torque;          // torque on each rigid body in space coords
   double **quat;            // quaternion of each rigid body
-  int *imagebody;           // image flags of xcm of each rigid body
+  tagint *imagebody;        // image flags of xcm of each rigid body
   double **fflag;           // flag for on/off of center-of-mass force
   double **tflag;           // flag for on/off of center-of-mass torque
   double **langextra;       // Langevin thermostat forces and torques
diff --git a/src/fix_rigid_nve.cpp b/src/fix_rigid_nve.cpp
index cd04526d89..019fed2876 100644
--- a/src/fix_rigid_nve.cpp
+++ b/src/fix_rigid_nve.cpp
@@ -155,7 +155,7 @@ void FixRigidNVE::final_integrate()
 
   // sum over atoms to get force and torque on rigid body
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
   double **f = atom->f;
   int nlocal = atom->nlocal;
@@ -182,9 +182,9 @@ void FixRigidNVE::final_integrate()
     sum[ibody][1] += f[i][1];
     sum[ibody][2] += f[i][2];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     if (triclinic == 0) {
       xunwrap = x[i][0] + xbox*xprd;
diff --git a/src/fix_rigid_nvt.cpp b/src/fix_rigid_nvt.cpp
index a02ab54669..4598983230 100644
--- a/src/fix_rigid_nvt.cpp
+++ b/src/fix_rigid_nvt.cpp
@@ -300,7 +300,7 @@ void FixRigidNVT::final_integrate()
 
   // sum over atoms to get force and torque on rigid body
 
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
   double **f = atom->f;
   int nlocal = atom->nlocal;
@@ -327,9 +327,9 @@ void FixRigidNVT::final_integrate()
     sum[ibody][1] += f[i][1];
     sum[ibody][2] += f[i][2];
 
-    xbox = (image[i] & 1023) - 512;
-    ybox = (image[i] >> 10 & 1023) - 512;
-    zbox = (image[i] >> 20) - 512;
+    xbox = (image[i] & IMGMASK) - IMGMAX;
+    ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+    zbox = (image[i] >> IMG2BITS) - IMGMAX;
 
     if (triclinic == 0) {
       xunwrap = x[i][0] + xbox*xprd;
diff --git a/src/fix_spring_rg.cpp b/src/fix_spring_rg.cpp
index 785fd40e3e..e17aa8966c 100644
--- a/src/fix_spring_rg.cpp
+++ b/src/fix_spring_rg.cpp
@@ -105,7 +105,7 @@ void FixSpringRG::post_force(int vflag)
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   int nlocal = atom->nlocal;
 
@@ -118,9 +118,9 @@ void FixSpringRG::post_force(int vflag)
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
       term1 = 2.0 * k * (1.0 - rg0/rg);
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
diff --git a/src/fix_spring_self.cpp b/src/fix_spring_self.cpp
index 675a53e495..fb2120d4cb 100644
--- a/src/fix_spring_self.cpp
+++ b/src/fix_spring_self.cpp
@@ -75,7 +75,7 @@ FixSpringSelf::FixSpringSelf(LAMMPS *lmp, int narg, char **arg) :
 
   double **x = atom->x;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double xprd = domain->xprd;
@@ -85,9 +85,9 @@ FixSpringSelf::FixSpringSelf(LAMMPS *lmp, int narg, char **arg) :
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       xoriginal[i][0] = x[i][0] + xbox*xprd;
       xoriginal[i][1] = x[i][1] + ybox*yprd;
       xoriginal[i][2] = x[i][2] + zbox*zprd;
@@ -158,7 +158,7 @@ void FixSpringSelf::post_force(int vflag)
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   double xprd = domain->xprd;
@@ -170,9 +170,9 @@ void FixSpringSelf::post_force(int vflag)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xoriginal[i][0];
       dy = x[i][1] + ybox*yprd - xoriginal[i][1];
       dz = x[i][2] + zbox*zprd - xoriginal[i][2];
diff --git a/src/fix_store_state.cpp b/src/fix_store_state.cpp
index 1554bf5191..579de00063 100644
--- a/src/fix_store_state.cpp
+++ b/src/fix_store_state.cpp
@@ -789,7 +789,7 @@ void FixStoreState::pack_zs_triclinic(int n)
 void FixStoreState::pack_xu(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -797,7 +797,7 @@ void FixStoreState::pack_xu(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      vbuf[n] = x[i][0] + ((image[i] & 1023) - 512) * xprd;
+      vbuf[n] = x[i][0] + ((image[i] & IMGMASK) - IMGMAX) * xprd;
       if (comflag) vbuf[n] -= cm[0];
     } else vbuf[n] = 0.0;
     n += nvalues;
@@ -809,7 +809,7 @@ void FixStoreState::pack_xu(int n)
 void FixStoreState::pack_yu(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -817,7 +817,7 @@ void FixStoreState::pack_yu(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      vbuf[n] = x[i][1] + ((image[i] >> 10 & 1023) - 512) * yprd;
+      vbuf[n] = x[i][1] + ((image[i] >> IMGBITS & IMGMASK) - IMGMAX) * yprd;
       if (comflag) vbuf[n] -= cm[1];
     } else vbuf[n] = 0.0;
     n += nvalues;
@@ -829,7 +829,7 @@ void FixStoreState::pack_yu(int n)
 void FixStoreState::pack_zu(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -837,7 +837,7 @@ void FixStoreState::pack_zu(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      vbuf[n] = x[i][2] + ((image[i] >> 20) - 512) * zprd;
+      vbuf[n] = x[i][2] + ((image[i] >> IMG2BITS) - IMGMAX) * zprd;
       if (comflag) vbuf[n] -= cm[2];
     } else vbuf[n] = 0.0;
     n += nvalues;
@@ -849,7 +849,7 @@ void FixStoreState::pack_zu(int n)
 void FixStoreState::pack_xu_triclinic(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -858,9 +858,9 @@ void FixStoreState::pack_xu_triclinic(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       vbuf[n] = x[i][0] + h[0]*xbox + h[5]*ybox + h[4]*zbox;
       if (comflag) vbuf[n] -= cm[0];
     } else vbuf[n] = 0.0;
@@ -873,7 +873,7 @@ void FixStoreState::pack_xu_triclinic(int n)
 void FixStoreState::pack_yu_triclinic(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -882,8 +882,8 @@ void FixStoreState::pack_yu_triclinic(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       vbuf[n] = x[i][1] + h[1]*ybox + h[3]*zbox;
       if (comflag) vbuf[n] -= cm[1];
     } else vbuf[n] = 0.0;
@@ -896,7 +896,7 @@ void FixStoreState::pack_yu_triclinic(int n)
 void FixStoreState::pack_zu_triclinic(int n)
 {
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
@@ -905,7 +905,7 @@ void FixStoreState::pack_zu_triclinic(int n)
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      zbox = (image[i] >> 20) - 512;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       vbuf[n] = x[i][2] + h[2]*zbox;
       if (comflag) vbuf[n] -= cm[2];
     } else vbuf[n] = 0.0;
@@ -917,12 +917,12 @@ void FixStoreState::pack_zu_triclinic(int n)
 
 void FixStoreState::pack_ix(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
-    if (mask[i] & groupbit) vbuf[n] = (image[i] & 1023) - 512;
+    if (mask[i] & groupbit) vbuf[n] = (image[i] & IMGMASK) - IMGMAX;
     else vbuf[n] = 0.0;
     n += nvalues;
   }
@@ -932,12 +932,12 @@ void FixStoreState::pack_ix(int n)
 
 void FixStoreState::pack_iy(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
-    if (mask[i] & groupbit) vbuf[n] = (image[i] >> 10 & 1023) - 512;
+    if (mask[i] & groupbit) vbuf[n] = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
     else vbuf[n] = 0.0;
     n += nvalues;
   }
@@ -947,12 +947,12 @@ void FixStoreState::pack_iy(int n)
 
 void FixStoreState::pack_iz(int n)
 {
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
 
   for (int i = 0; i < nlocal; i++) {
-    if (mask[i] & groupbit) vbuf[n] = (image[i] >> 20) - 512;
+    if (mask[i] & groupbit) vbuf[n] = (image[i] >> IMG2BITS) - IMGMAX;
     else vbuf[n] = 0.0;
     n += nvalues;
   }
diff --git a/src/fix_tmd.cpp b/src/fix_tmd.cpp
index 1e5ec70e78..71efd01bdf 100644
--- a/src/fix_tmd.cpp
+++ b/src/fix_tmd.cpp
@@ -93,7 +93,7 @@ FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) :
 
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double **x = atom->x;
   double *mass = atom->mass;
   int nlocal = atom->nlocal;
@@ -108,9 +108,9 @@ FixTMD::FixTMD(LAMMPS *lmp, int narg, char **arg) :
 
   for (int i = 0; i < nlocal; i++) {
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xf[i][0];
       dy = x[i][1] + ybox*yprd - xf[i][1];
       dz = x[i][2] + zbox*zprd - xf[i][2];
@@ -198,7 +198,7 @@ void FixTMD::initial_integrate(int vflag)
   double **v = atom->v;
   double **f = atom->f;
   double *mass = atom->mass;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int *type = atom->type;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
@@ -216,9 +216,9 @@ void FixTMD::initial_integrate(int vflag)
       dxold = xold[i][0] - xf[i][0];
       dyold = xold[i][1] - xf[i][1];
       dzold = xold[i][2] - xf[i][2];
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = x[i][0] + xbox*xprd - xf[i][0];
       dy = x[i][1] + ybox*yprd - xf[i][1];
       dz = x[i][2] + zbox*zprd - xf[i][2];
@@ -258,9 +258,9 @@ void FixTMD::initial_integrate(int vflag)
       dxold = xold[i][0] - xf[i][0];
       dyold = xold[i][1] - xf[i][1];
       dzold = xold[i][2] - xf[i][2];
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       xback = x[i][0] + xbox*xprd + gamma_back*dxold;
       yback = x[i][1] + ybox*yprd + gamma_back*dyold;
       zback = x[i][2] + zbox*zprd + gamma_back*dzold;
@@ -314,9 +314,9 @@ void FixTMD::initial_integrate(int vflag)
       x[i][2] += gamma_forward*dzold;
       v[i][2] += gamma_forward*dzold/dtv;
       f[i][2] += gamma_forward*dzold/dtv/dtfm;
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       xold[i][0] = x[i][0] + xbox*xprd;
       xold[i][1] = x[i][1] + ybox*yprd;
       xold[i][2] = x[i][2] + zbox*zprd;
diff --git a/src/group.cpp b/src/group.cpp
index dfccc77f46..e15891d3a2 100644
--- a/src/group.cpp
+++ b/src/group.cpp
@@ -733,7 +733,7 @@ void Group::xcm(int igroup, double masstotal, double *cm)
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -750,9 +750,9 @@ void Group::xcm(int igroup, double masstotal, double *cm)
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         massone = rmass[i];
         cmone[0] += (x[i][0] + xbox*xprd) * massone;
         cmone[1] += (x[i][1] + ybox*yprd) * massone;
@@ -761,9 +761,9 @@ void Group::xcm(int igroup, double masstotal, double *cm)
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         massone = mass[type[i]];
         cmone[0] += (x[i][0] + xbox*xprd) * massone;
         cmone[1] += (x[i][1] + ybox*yprd) * massone;
@@ -794,7 +794,7 @@ void Group::xcm(int igroup, double masstotal, double *cm, int iregion)
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -811,9 +811,9 @@ void Group::xcm(int igroup, double masstotal, double *cm, int iregion)
   if (rmass) {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         massone = rmass[i];
         cmone[0] += (x[i][0] + xbox*xprd) * massone;
         cmone[1] += (x[i][1] + ybox*yprd) * massone;
@@ -822,9 +822,9 @@ void Group::xcm(int igroup, double masstotal, double *cm, int iregion)
   } else {
     for (int i = 0; i < nlocal; i++)
       if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
-        xbox = (image[i] & 1023) - 512;
-        ybox = (image[i] >> 10 & 1023) - 512;
-        zbox = (image[i] >> 20) - 512;
+        xbox = (image[i] & IMGMASK) - IMGMAX;
+        ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+        zbox = (image[i] >> IMG2BITS) - IMGMAX;
         massone = mass[type[i]];
         cmone[0] += (x[i][0] + xbox*xprd) * massone;
         cmone[1] += (x[i][1] + ybox*yprd) * massone;
@@ -1071,7 +1071,7 @@ double Group::gyration(int igroup, double masstotal, double *cm)
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -1085,9 +1085,9 @@ double Group::gyration(int igroup, double masstotal, double *cm)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
@@ -1116,7 +1116,7 @@ double Group::gyration(int igroup, double masstotal, double *cm, int iregion)
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -1130,9 +1130,9 @@ double Group::gyration(int igroup, double masstotal, double *cm, int iregion)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
@@ -1161,7 +1161,7 @@ void Group::angmom(int igroup, double *cm, double *lmom)
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -1176,9 +1176,9 @@ void Group::angmom(int igroup, double *cm, double *lmom)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
@@ -1207,7 +1207,7 @@ void Group::angmom(int igroup, double *cm, double *lmom, int iregion)
   double **v = atom->v;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -1222,9 +1222,9 @@ void Group::angmom(int igroup, double *cm, double *lmom, int iregion)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
@@ -1251,7 +1251,7 @@ void Group::torque(int igroup, double *cm, double *tq)
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
@@ -1264,9 +1264,9 @@ void Group::torque(int igroup, double *cm, double *tq)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
@@ -1292,7 +1292,7 @@ void Group::torque(int igroup, double *cm, double *tq, int iregion)
   double **x = atom->x;
   double **f = atom->f;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
@@ -1305,9 +1305,9 @@ void Group::torque(int igroup, double *cm, double *tq, int iregion)
 
   for (int i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
@@ -1333,7 +1333,7 @@ void Group::inertia(int igroup, double *cm, double itensor[3][3])
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -1350,9 +1350,9 @@ void Group::inertia(int igroup, double *cm, double itensor[3][3])
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
@@ -1387,7 +1387,7 @@ void Group::inertia(int igroup, double *cm, double itensor[3][3], int iregion)
   double **x = atom->x;
   int *mask = atom->mask;
   int *type = atom->type;
-  int *image = atom->image;
+  tagint *image = atom->image;
   double *mass = atom->mass;
   double *rmass = atom->rmass;
   int nlocal = atom->nlocal;
@@ -1404,9 +1404,9 @@ void Group::inertia(int igroup, double *cm, double itensor[3][3], int iregion)
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit && region->match(x[i][0],x[i][1],x[i][2])) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMAX;
       dx = (x[i][0] + xbox*xprd) - cm[0];
       dy = (x[i][1] + ybox*yprd) - cm[1];
       dz = (x[i][2] + zbox*zprd) - cm[2];
diff --git a/src/lmptype.h b/src/lmptype.h
index 5eca877ec9..7a4288b0e4 100644
--- a/src/lmptype.h
+++ b/src/lmptype.h
@@ -1,11 +1,11 @@
-/* ----------------------------------------------------------------------
+/* -*- c++ -*- ----------------------------------------------------------
    LAMMPS - Large-scale Atomic/Molecular Massively Parallel Simulator
    http://lammps.sandia.gov, Sandia National Laboratories
    Steve Plimpton, sjplimp@sandia.gov
 
    Copyright (2003) Sandia Corporation.  Under the terms of Contract
    DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government retains
-   certain rights in this software.  This software is distributed under
+   certain rights in this software.  This software is distributed under 
    the GNU General Public License.
 
    See the README file in the top-level LAMMPS directory.
@@ -91,9 +91,15 @@ typedef int64_t bigint;
 #define ATOTAGINT atoi
 #define ATOBIGINT ATOLL
 
+#define IMGMASK 1023
+#define IMGMAX 512
+#define IMGBITS 10
+#define IMG2BITS 20
+
 #endif
 
 // for molecular problems that exceed 2 billion (2^31) atoms
+// or problems where atoms wrap around the periodic box more than 512 times
 // 32-bit smallint, 64-bit tagint and bigint
 
 #ifdef LAMMPS_BIGBIG
@@ -115,6 +121,11 @@ typedef int64_t bigint;
 #define ATOTAGINT ATOLL
 #define ATOBIGINT ATOLL
 
+#define IMGMASK 2097151
+#define IMGMAX 1048576
+#define IMGBITS 21
+#define IMG2BITS 42
+
 #endif
 
 // for machines that do not support 64-bit ints
@@ -139,6 +150,11 @@ typedef int bigint;
 #define ATOTAGINT atoi
 #define ATOBIGINT atoi
 
+#define IMGMASK 1023
+#define IMGMAX 512
+#define IMGBITS 10
+#define IMG2BITS 20
+
 #endif
 
 }
diff --git a/src/read_dump.cpp b/src/read_dump.cpp
index c04c7e659c..85d333d40c 100644
--- a/src/read_dump.cpp
+++ b/src/read_dump.cpp
@@ -506,7 +506,7 @@ void ReadDump::atoms()
   // use irregular() in case atoms moved a long distance
 
   double **x = atom->x;
-  int *image = atom->image;
+  tagint *image = atom->image;
   nlocal = atom->nlocal;
   for (int i = 0; i < nlocal; i++) domain->remap(x[i],image[i]);
 
@@ -666,7 +666,7 @@ void ReadDump::process_atoms(int n)
 
   double **x = atom->x;
   double **v = atom->v;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   for (i = 0; i < n; i++) {
@@ -687,9 +687,9 @@ void ReadDump::process_atoms(int n)
 
       // current image flags
 
-      xbox = (image[m] & 1023) - 512;
-      ybox = (image[m] >> 10 & 1023) - 512;
-      zbox = (image[m] >> 20) - 512;
+      xbox = (image[m] & IMGMASK) - IMGMAX;
+      ybox = (image[m] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[m] >> IMG2BITS) - IMGMAX;
 
       // overwrite atom attributes with field info
       // start from field 1 since 0 = id, 1 will be skipped if type
@@ -728,7 +728,8 @@ void ReadDump::process_atoms(int n)
 
       // replace image flag in case changed by ix,iy,iz fields
 
-      image[m] = (xbox << 20) | (ybox << 10) | zbox;
+      image[m] = ((tagint) xbox << IMG2BITS) | 
+        ((tagint) ybox << IMGBITS) | zbox;
     }
   }
 
@@ -784,9 +785,9 @@ void ReadDump::process_atoms(int n)
     m = atom->nlocal;
 
     // set atom attributes from other dump file fields
-    // xyzbox = 512 is default value set by create_atom()
+    // xyzbox = IMGMAX is default value set by create_atom()
 
-    xbox = ybox = zbox = 512;
+    xbox = ybox = zbox = IMGMAX;
 
     for (ifield = 1; ifield < nfield; ifield++) {
       switch (fieldtype[ifield]) {
@@ -812,7 +813,8 @@ void ReadDump::process_atoms(int n)
 
       // replace image flag in case changed by ix,iy,iz fields
 
-      image[m] = (xbox << 20) | (ybox << 10) | zbox;
+      image[m] = ((tagint) xbox << IMG2BITS) | 
+        ((tagint) ybox << IMGBITS) | zbox;
     }
   }
 
diff --git a/src/replicate.cpp b/src/replicate.cpp
index 90101668b0..bfc92a780f 100644
--- a/src/replicate.cpp
+++ b/src/replicate.cpp
@@ -255,7 +255,8 @@ void Replicate::command(int narg, char **arg)
   AtomVec *old_avec = old->avec;
   AtomVec *avec = atom->avec;
 
-  int ix,iy,iz,image,atom_offset,mol_offset;
+  int ix,iy,iz,atom_offset,mol_offset;
+  tagint image;
   double x[3],lamda[3];
   double *coord;
   int tag_enable = atom->tag_enable;
@@ -276,7 +277,8 @@ void Replicate::command(int narg, char **arg)
 
           m = 0;
           while (m < n) {
-            image = (512 << 20) | (512 << 10) | 512;
+            image = ((tagint) IMGMAX << IMG2BITS) | 
+              ((tagint) IMGMASK << IMGBITS) | IMGMAX;
             if (triclinic == 0) {
               x[0] = buf[m+1] + ix*old_xprd;
               x[1] = buf[m+2] + iy*old_yprd;
diff --git a/src/set.cpp b/src/set.cpp
index eaa34538ba..4105f4a2f4 100644
--- a/src/set.cpp
+++ b/src/set.cpp
@@ -490,14 +490,15 @@ void Set::set(int keyword)
     // reset any or all of 3 image flags
 
     } else if (keyword == IMAGE) {
-      int xbox = (atom->image[i] & 1023) - 512;
-      int ybox = (atom->image[i] >> 10 & 1023) - 512;
-      int zbox = (atom->image[i] >> 20) - 512;
+      int xbox = (atom->image[i] & IMGMASK) - IMGMAX;
+      int ybox = (atom->image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      int zbox = (atom->image[i] >> IMG2BITS) - IMGMAX;
       if (ximageflag) xbox = ximage;
       if (yimageflag) ybox = yimage;
       if (zimageflag) zbox = zimage;
-      atom->image[i] = ((zbox + 512 & 1023) << 20) |
-        ((ybox + 512 & 1023) << 10) | (xbox + 512 & 1023);
+      atom->image[i] = ((zbox + (tagint) IMGMAX & IMGMASK) << IMG2BITS) |
+        ((ybox + (tagint) IMGMAX & IMGMASK) << IMGBITS) | 
+        (xbox + IMGMAX & IMGMASK);
 
     // set dipole moment
 
diff --git a/src/velocity.cpp b/src/velocity.cpp
index fa3712bbbd..bd66833170 100644
--- a/src/velocity.cpp
+++ b/src/velocity.cpp
@@ -715,7 +715,7 @@ void Velocity::zero_rotation()
   double **x = atom->x;
   double **v = atom->v;
   int *mask = atom->mask;
-  int *image = atom->image;
+  tagint *image = atom->image;
   int nlocal = atom->nlocal;
 
   int xbox,ybox,zbox;
@@ -726,9 +726,9 @@ void Velocity::zero_rotation()
 
   for (i = 0; i < nlocal; i++)
     if (mask[i] & groupbit) {
-      xbox = (image[i] & 1023) - 512;
-      ybox = (image[i] >> 10 & 1023) - 512;
-      zbox = (image[i] >> 20) - 512;
+      xbox = (image[i] & IMGMASK) - IMGMAX;
+      ybox = (image[i] >> IMGBITS & IMGMASK) - IMGMAX;
+      zbox = (image[i] >> IMG2BITS) - IMGMASK;
       dx = (x[i][0] + xbox*xprd) - xcm[0];
       dy = (x[i][1] + ybox*yprd) - xcm[1];
       dz = (x[i][2] + zbox*zprd) - xcm[2];
-- 
GitLab