diff --git a/doc/Makefile b/doc/Makefile
index e272fc253e029d3134e47d4655903b971902abf9..fd087f0344c32c1d5dfe45b516555e482060c7c9 100644
--- a/doc/Makefile
+++ b/doc/Makefile
@@ -6,6 +6,7 @@ BUILDDIR      = /tmp/lammps-docs-$(SHA1)
 RSTDIR        = $(BUILDDIR)/rst
 VENV          = $(BUILDDIR)/docenv
 TXT2RST       = $(VENV)/bin/txt2rst
+ANCHORCHECK   = $(VENV)/bin/doc_anchor_check
 
 PYTHON        = $(shell which python3)
 HAS_PYTHON3    = NO
@@ -50,7 +51,7 @@ clean:
 clean-spelling:
 	rm -rf spelling
 
-html: $(OBJECTS)
+html: $(OBJECTS) $(ANCHORCHECK)
 	@(\
 		. $(VENV)/bin/activate ;\
 		cp -r src/* $(RSTDIR)/ ;\
@@ -131,7 +132,7 @@ fetch:
 
 txt2html: utils/txt2html/txt2html.exe
 
-anchor_check : $(TXT2RST)
+anchor_check : $(ANCHORCHECK)
 	@(\
 		. $(VENV)/bin/activate ;\
 		doc_anchor_check src/*.txt ;\
@@ -162,7 +163,7 @@ $(VENV):
 		deactivate;\
 	)
 
-$(TXT2RST): $(VENV)
+$(TXT2RST) $(ANCHORCHECK): $(VENV)
 	@( \
 		. $(VENV)/bin/activate; \
 		(cd utils/converters;\
diff --git a/doc/src/Section_example.txt b/doc/src/Section_example.txt
index 60a5ed128502b71bb80784a16f420c21b522ab97..0fadaf11fd430f5111e5096c64605c5dc00fa69e 100644
--- a/doc/src/Section_example.txt
+++ b/doc/src/Section_example.txt
@@ -25,9 +25,7 @@ files and image files.
 
 If you uncomment the "dump"_dump.html command in the input script, a
 text dump file will be produced, which can be animated by various
-"visualization programs"_http://lammps.sandia.gov/viz.html.  It can
-also be animated using the xmovie tool described in the "Additional
-Tools"_Section_tools.html section of the LAMMPS documentation.
+"visualization programs"_http://lammps.sandia.gov/viz.html.
 
 If you uncomment the "dump image"_dump.html command in the input
 script, and assuming you have built LAMMPS with a JPG library, JPG
diff --git a/doc/src/Section_tools.txt b/doc/src/Section_tools.txt
index b34cac4dc035f922237261b483587991d3bd459a..03611c7cdb2db0a8cf57183b34e68aaf920fca33 100644
--- a/doc/src/Section_tools.txt
+++ b/doc/src/Section_tools.txt
@@ -47,7 +47,7 @@ own sub-directories with their own Makefiles and/or README files.
 "ch2lmp"_#charmm
 "chain"_#chain
 "colvars"_#colvars
-"createatoms"_#createtools
+"createatoms"_#createatoms
 "drude"_#drude
 "eam database"_#eamdb
 "eam generate"_#eamgn
@@ -159,7 +159,7 @@ gmail.com) at ICTP, Italy.
 
 :line
 
-createatoms tool :h4,link(create)
+createatoms tool :h4,link(createatoms)
 
 The tools/createatoms directory contains a Fortran program called
 createAtoms.f which can generate a variety of interesting crystal
diff --git a/doc/src/dump_molfile.txt b/doc/src/dump_molfile.txt
index 3494ba9a915427819a020a99ab1b675ded464b9f..7e68490a68e013c42f13883d9b7d1f9044929ce8 100644
--- a/doc/src/dump_molfile.txt
+++ b/doc/src/dump_molfile.txt
@@ -34,10 +34,7 @@ to one or more files every N timesteps in one of several formats.
 Only information for atoms in the specified group is dumped.  This
 specific dump style uses molfile plugins that are bundled with the
 "VMD"_http://www.ks.uiuc.edu/Research/vmd molecular visualization and
-analysis program.  See "Section 9"_Section_tools.html#vmd of the
-manual and the tools/lmp2vmd/README.txt file for more information
-about support in VMD for reading and visualizing native LAMMPS dump
-files.
+analysis program.
 
 Unless the filename contains a * character, the output will be written
 to one single file with the specified format. Otherwise there will be
diff --git a/src/MANYBODY/pair_airebo.cpp b/src/MANYBODY/pair_airebo.cpp
index cacc8b3416cbc0b2bc3d1b0d0ace04cbcd75a3b2..bf48c5d9aeba46eac255f6397923d21ef926d6bb 100644
--- a/src/MANYBODY/pair_airebo.cpp
+++ b/src/MANYBODY/pair_airebo.cpp
@@ -709,13 +709,13 @@ void PairAIREBO::FLJ(int eflag, int vflag)
                     atomm = m;
                     delkmS[0] = delkm[0];
                     delkmS[1] = delkm[1];
-                        delkmS[2] = delkm[2];
+                    delkmS[2] = delkm[2];
                     rkmS = rkm;
                     wkmS = wkm;
                     dwkmS = dwkm;
                     deljmS[0] = deljm[0];
                     deljmS[1] = deljm[1];
-                       deljmS[2] = deljm[2];
+                    deljmS[2] = deljm[2];
                     rmjS = rmj;
                     wmjS = wmj;
                     dwmjS = dwmj;
diff --git a/src/USER-OMP/pair_airebo_omp.cpp b/src/USER-OMP/pair_airebo_omp.cpp
index 27089fd6b3ef4ba673b48be9bee265945652dde8..fb1308990fd7c574175c0bd84a9eb5395c5fdab6 100644
--- a/src/USER-OMP/pair_airebo_omp.cpp
+++ b/src/USER-OMP/pair_airebo_omp.cpp
@@ -84,2689 +84,2695 @@ void PairAIREBOOMP::compute(int eflag, int vflag)
 }
 
 /* ----------------------------------------------------------------------
-   Bij function
+   create REBO neighbor list from main neighbor list
+   REBO neighbor list stores neighbors of ghost atoms
 ------------------------------------------------------------------------- */
 
-double PairAIREBOOMP::bondorder_thr(int i, int j, double rij[3], double rijmag,
-                                    double VA, int vflag_atom, ThrData * const thr)
+void PairAIREBOOMP::REBO_neigh_thr()
 {
-  int atomi,atomj,k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
-  int itype,jtype,ktype,ltype,ntype;
-  double rik[3],rjl[3],rkn[3],rji[3],rki[3],rlj[3],rknmag,dNki,dwjl,bij;
-  double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
-  double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
-  double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ,Nki,Nlj,dS;
-  double lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
-  double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
-  double dN2[2],dN3[3];
-  double dcosjikdrj[3],dcosijldrj[3],dcosijldrl[3];
-  double Tij;
-  double r32[3],r32mag,cos321,r43[3],r13[3];
-  double dNlj;
-  double om1234,rln[3];
-  double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
-  double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
-  double cross321[3],cross234[3],prefactor,SpN;
-  double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
-  double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
-  double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
-  double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
-  double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
-  double F23[3],F12[3],F34[3],F31[3],F24[3],fi[3],fj[3],fk[3],fl[3];
-  double f1[3],f2[3],f3[3],f4[4];
-  double dcut321,PijS,PjiS;
-  double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
-  int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
+  const int nthreads = comm->nthreads;
 
-  const double * const * const x = atom->x;
-  double * const * const f = thr->get_f();
-  int *type = atom->type;
+  if (atom->nmax > maxlocal) {
+    maxlocal = atom->nmax;
+    memory->destroy(REBO_numneigh);
+    memory->sfree(REBO_firstneigh);
+    memory->destroy(nC);
+    memory->destroy(nH);
+    memory->create(REBO_numneigh,maxlocal,"AIREBO:numneigh");
+    REBO_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *),
+                                               "AIREBO:firstneigh");
+    memory->create(nC,maxlocal,"AIREBO:nC");
+    memory->create(nH,maxlocal,"AIREBO:nH");
+  }
 
-  atomi = i;
-  atomj = j;
-  itype = map[type[i]];
-  jtype = map[type[j]];
-  wij = Sp(rijmag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
-  NijC = nC[i]-(wij*kronecker(jtype,0));
-  NijH = nH[i]-(wij*kronecker(jtype,1));
-  NjiC = nC[j]-(wij*kronecker(itype,0));
-  NjiH = nH[j]-(wij*kronecker(itype,1));
-  bij = 0.0;
-  tmp = 0.0;
-  tmp2 = 0.0;
-  tmp3 = 0.0;
-  dgdc = 0.0;
-  dgdN = 0.0;
-  NconjtmpI = 0.0;
-  NconjtmpJ = 0.0;
-  Etmp = 0.0;
+#if defined(_OPENMP)
+#pragma omp parallel default(none)
+#endif
+  {
+    int i,j,ii,jj,n,jnum,itype,jtype;
+    double xtmp,ytmp,ztmp,delx,dely,delz,rsq,dS;
+    int *ilist,*jlist,*numneigh,**firstneigh;
+    int *neighptr;
 
-  REBO_neighs = REBO_firstneigh[i];
-  for (k = 0; k < REBO_numneigh[i]; k++) {
-    atomk = REBO_neighs[k];
-    if (atomk != atomj) {
-      ktype = map[type[atomk]];
-      rik[0] = x[atomi][0]-x[atomk][0];
-      rik[1] = x[atomi][1]-x[atomk][1];
-      rik[2] = x[atomi][2]-x[atomk][2];
-      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-      lamdajik = 4.0*kronecker(itype,1) *
-        ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
-      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
-      Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
-        (wik*kronecker(itype,1));
-      cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
-        (rijmag*rikmag);
-      cosjik = MIN(cosjik,1.0);
-      cosjik = MAX(cosjik,-1.0);
+    double **x = atom->x;
+    int *type = atom->type;
 
-      // evaluate splines g and derivatives dg
+    const int allnum = list->inum + list->gnum;
+    ilist = list->ilist;
+    numneigh = list->numneigh;
+    firstneigh = list->firstneigh;
 
-      g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
-      Etmp = Etmp+(wik*g*exp(lamdajik));
-      tmp3 = tmp3+(wik*dgdN*exp(lamdajik));
-      NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
-    }
-  }
+#if defined(_OPENMP)
+    const int tid = omp_get_thread_num();
+#else
+    const int tid = 0;
+#endif
 
-  PijS = 0.0;
-  dN2[0] = 0.0;
-  dN2[1] = 0.0;
-  PijS = PijSpline(NijC,NijH,itype,jtype,dN2);
-  pij = 1.0/sqrt(1.0+Etmp+PijS);
-  tmp = -0.5*pij*pij*pij;
+    const int iidelta = 1 + allnum/nthreads;
+    const int iifrom = tid*iidelta;
+    const int iito = ((iifrom+iidelta)>allnum) ? allnum : (iifrom+iidelta);
 
-  const double invrijm = 1.0/rijmag;
-  const double invrijm2 = invrijm*invrijm;
+    // store all REBO neighs of owned and ghost atoms
+    // scan full neighbor list of I
 
-  // pij forces
+    // each thread has its own page allocator
+    MyPage<int> &ipg = ipage[tid];
+    ipg.reset();
 
-  REBO_neighs = REBO_firstneigh[i];
-  for (k = 0; k < REBO_numneigh[i]; k++) {
-    atomk = REBO_neighs[k];
-    if (atomk != atomj) {
-      ktype = map[type[atomk]];
-      rik[0] = x[atomi][0]-x[atomk][0];
-      rik[1] = x[atomi][1]-x[atomk][1];
-      rik[2] = x[atomi][2]-x[atomk][2];
-      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-      lamdajik = 4.0*kronecker(itype,1) *
-        ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
-      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+    for (ii = iifrom; ii < iito; ii++) {
+      i = ilist[ii];
 
-      const double invrikm = 1.0/rikmag;
-      const double invrijkm = invrijm*invrikm;
-      const double invrikm2 = invrikm*invrikm;
+      n = 0;
+      neighptr = ipg.vget();
 
-      cosjik = (rij[0]*rik[0] + rij[1]*rik[1] + rij[2]*rik[2]) * invrijkm;
-      cosjik = MIN(cosjik,1.0);
-      cosjik = MAX(cosjik,-1.0);
+      xtmp = x[i][0];
+      ytmp = x[i][1];
+      ztmp = x[i][2];
+      itype = map[type[i]];
+      nC[i] = nH[i] = 0.0;
+      jlist = firstneigh[i];
+      jnum = numneigh[i];
 
-      dcosjikdri[0] = ((rij[0]+rik[0])*invrijkm) -
-        (cosjik*((rij[0]*invrijm2)+(rik[0]*invrikm2)));
-      dcosjikdri[1] = ((rij[1]+rik[1])*invrijkm) -
-        (cosjik*((rij[1]*invrijm2)+(rik[1]*invrikm2)));
-      dcosjikdri[2] = ((rij[2]+rik[2])*invrijkm) -
-        (cosjik*((rij[2]*invrijm2)+(rik[2]*invrikm2)));
-      dcosjikdrk[0] = (-rij[0]*invrijkm) + (cosjik*(rik[0]*invrikm2));
-      dcosjikdrk[1] = (-rij[1]*invrijkm) + (cosjik*(rik[1]*invrikm2));
-      dcosjikdrk[2] = (-rij[2]*invrijkm) + (cosjik*(rik[2]*invrikm2));
-      dcosjikdrj[0] = (-rik[0]*invrijkm) + (cosjik*(rij[0]*invrijm2));
-      dcosjikdrj[1] = (-rik[1]*invrijkm) + (cosjik*(rij[1]*invrijm2));
-      dcosjikdrj[2] = (-rik[2]*invrijkm) + (cosjik*(rij[2]*invrijm2));
+      for (jj = 0; jj < jnum; jj++) {
+        j = jlist[jj];
+        j &= NEIGHMASK;
+        jtype = map[type[j]];
+        delx = xtmp - x[j][0];
+        dely = ytmp - x[j][1];
+        delz = ztmp - x[j][2];
+        rsq = delx*delx + dely*dely + delz*delz;
 
-      g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
-      tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
-      fj[0] = -tmp2*dcosjikdrj[0];
-      fj[1] = -tmp2*dcosjikdrj[1];
-      fj[2] = -tmp2*dcosjikdrj[2];
-      fi[0] = -tmp2*dcosjikdri[0];
-      fi[1] = -tmp2*dcosjikdri[1];
-      fi[2] = -tmp2*dcosjikdri[2];
-      fk[0] = -tmp2*dcosjikdrk[0];
-      fk[1] = -tmp2*dcosjikdrk[1];
-      fk[2] = -tmp2*dcosjikdrk[2];
+        if (rsq < rcmaxsq[itype][jtype]) {
+          neighptr[n++] = j;
+          if (jtype == 0)
+            nC[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
+          else
+            nH[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
+        }
+      }
 
-      tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
-      fj[0] -= tmp2*(-rij[0]*invrijm);
-      fj[1] -= tmp2*(-rij[1]*invrijm);
-      fj[2] -= tmp2*(-rij[2]*invrijm);
-      fi[0] -= tmp2*((-rik[0]*invrikm)+(rij[0]*invrijm));
-      fi[1] -= tmp2*((-rik[1]*invrikm)+(rij[1]*invrijm));
-      fi[2] -= tmp2*((-rik[2]*invrikm)+(rij[2]*invrijm));
-      fk[0] -= tmp2*(rik[0]*invrikm);
-      fk[1] -= tmp2*(rik[1]*invrikm);
-      fk[2] -= tmp2*(rik[2]*invrikm);
+      REBO_firstneigh[i] = neighptr;
+      REBO_numneigh[i] = n;
+      ipg.vgot(n);
+      if (ipg.status())
+        error->one(FLERR,"REBO list overflow, boost neigh_modify one");
+    }
+  }
+}
 
-      // coordination forces
+/* ----------------------------------------------------------------------
+   REBO forces and energy
+------------------------------------------------------------------------- */
 
-      // dwik forces
+void PairAIREBOOMP::FREBO_thr(int ifrom, int ito, int evflag, int eflag,
+                              int vflag_atom, double *pv0, ThrData * const thr)
+{
+  int i,j,k,m,ii,itype,jtype;
+  tagint itag,jtag;
+  double delx,dely,delz,evdwl,fpair,xtmp,ytmp,ztmp;
+  double rsq,rij,wij;
+  double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA;
+  double dwij,del[3];
+  int *ilist,*REBO_neighs;
 
-      tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))*invrikm;
-      fi[0] -= tmp2*rik[0];
-      fi[1] -= tmp2*rik[1];
-      fi[2] -= tmp2*rik[2];
-      fk[0] += tmp2*rik[0];
-      fk[1] += tmp2*rik[1];
-      fk[2] += tmp2*rik[2];
+  evdwl = 0.0;
 
-      // PIJ forces
+  const double * const * const x = atom->x;
+  double * const * const f = thr->get_f();
+  int *type = atom->type;
+  tagint *tag = atom->tag;
+  int nlocal = atom->nlocal;
 
-      tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)*invrikm;
-      fi[0] -= tmp2*rik[0];
-      fi[1] -= tmp2*rik[1];
-      fi[2] -= tmp2*rik[2];
-      fk[0] += tmp2*rik[0];
-      fk[1] += tmp2*rik[1];
-      fk[2] += tmp2*rik[2];
+  ilist = list->ilist;
 
-      // dgdN forces
+  // two-body interactions from REBO neighbor list, skip half of them
 
-      tmp2 = VA*.5*(tmp*tmp3*dwik)*invrikm;
-      fi[0] -= tmp2*rik[0];
-      fi[1] -= tmp2*rik[1];
-      fi[2] -= tmp2*rik[2];
-      fk[0] += tmp2*rik[0];
-      fk[1] += tmp2*rik[1];
-      fk[2] += tmp2*rik[2];
+  for (ii = ifrom; ii < ito; ii++) {
+    i = ilist[ii];
+    itag = tag[i];
+    itype = map[type[i]];
+    xtmp = x[i][0];
+    ytmp = x[i][1];
+    ztmp = x[i][2];
+    REBO_neighs = REBO_firstneigh[i];
 
-      f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
-      f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
-      f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
+    for (k = 0; k < REBO_numneigh[i]; k++) {
+      j = REBO_neighs[k];
+      jtag = tag[j];
 
-      if (vflag_atom) {
-        rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
-        rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
-        v_tally3_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr);
+      if (itag > jtag) {
+        if ((itag+jtag) % 2 == 0) continue;
+      } else if (itag < jtag) {
+        if ((itag+jtag) % 2 == 1) continue;
+      } else {
+        if (x[j][2] < ztmp) continue;
+        if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+        if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
       }
-    }
-  }
 
-  tmp = 0.0;
-  tmp2 = 0.0;
-  tmp3 = 0.0;
-  Etmp = 0.0;
+      jtype = map[type[j]];
 
-  REBO_neighs = REBO_firstneigh[j];
-  for (l = 0; l < REBO_numneigh[j]; l++) {
-    atoml = REBO_neighs[l];
-    if (atoml != atomi) {
-      ltype = map[type[atoml]];
-      rjl[0] = x[atomj][0]-x[atoml][0];
-      rjl[1] = x[atomj][1]-x[atoml][1];
-      rjl[2] = x[atomj][2]-x[atoml][2];
-      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-      lamdaijl = 4.0*kronecker(jtype,1) *
-        ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
-      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
-      Nlj = nC[atoml]-(wjl*kronecker(jtype,0)) +
-        nH[atoml]-(wjl*kronecker(jtype,1));
-      cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
-        (rijmag*rjlmag);
-      cosijl = MIN(cosijl,1.0);
-      cosijl = MAX(cosijl,-1.0);
+      delx = x[i][0] - x[j][0];
+      dely = x[i][1] - x[j][1];
+      delz = x[i][2] - x[j][2];
+      rsq = delx*delx + dely*dely + delz*delz;
+      rij = sqrt(rsq);
+      wij = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+      if (wij <= TOL) continue;
 
-      // evaluate splines g and derivatives dg
+      Qij = Q[itype][jtype];
+      Aij = A[itype][jtype];
+      alphaij = alpha[itype][jtype];
 
-      g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
-      Etmp = Etmp+(wjl*g*exp(lamdaijl));
-      tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
-      NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
-    }
-  }
+      VR = wij*(1.0+(Qij/rij)) * Aij*exp(-alphaij*rij);
+      pre = wij*Aij * exp(-alphaij*rij);
+      dVRdi = pre * ((-alphaij)-(Qij/rsq)-(Qij*alphaij/rij));
+      dVRdi += VR/wij * dwij;
 
-  PjiS = 0.0;
-  dN2[0] = 0.0;
-  dN2[1] = 0.0;
-  PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2);
-  pji = 1.0/sqrt(1.0+Etmp+PjiS);
-  tmp = -0.5*pji*pji*pji;
+      VA = dVA = 0.0;
+      for (m = 0; m < 3; m++) {
+        term = -wij * BIJc[itype][jtype][m] * exp(-Beta[itype][jtype][m]*rij);
+        VA += term;
+        dVA += -Beta[itype][jtype][m] * term;
+      }
+      dVA += VA/wij * dwij;
+      del[0] = delx;
+      del[1] = dely;
+      del[2] = delz;
+      bij = bondorder_thr(i,j,del,rij,VA,vflag_atom,thr);
+      dVAdi = bij*dVA;
 
-  REBO_neighs = REBO_firstneigh[j];
-  for (l = 0; l < REBO_numneigh[j]; l++) {
-    atoml = REBO_neighs[l];
-    if (atoml != atomi) {
-      ltype = map[type[atoml]];
-      rjl[0] = x[atomj][0]-x[atoml][0];
-      rjl[1] = x[atomj][1]-x[atoml][1];
-      rjl[2] = x[atomj][2]-x[atoml][2];
-      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-      lamdaijl = 4.0*kronecker(jtype,1) *
-        ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
-      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+      fpair = -(dVRdi+dVAdi) / rij;
+      f[i][0] += delx*fpair;
+      f[i][1] += dely*fpair;
+      f[i][2] += delz*fpair;
+      f[j][0] -= delx*fpair;
+      f[j][1] -= dely*fpair;
+      f[j][2] -= delz*fpair;
 
-      const double invrjlm = 1.0/rjlmag;
-      const double invrijlm = invrijm*invrjlm;
-      const double invrjlm2 = invrjlm*invrjlm;
+      if (eflag) *pv0 += evdwl = VR + bij*VA;
+      if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+                               evdwl,0.0,fpair,delx,dely,delz,thr);
+    }
+  }
+}
 
-      cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])))
-        * invrijlm;
+/* ----------------------------------------------------------------------
+   compute LJ forces and energy
+   find 3- and 4-step paths between atoms I,J via REBO neighbor lists
+------------------------------------------------------------------------- */
 
-      cosijl = MIN(cosijl,1.0);
-      cosijl = MAX(cosijl,-1.0);
+void PairAIREBOOMP::FLJ_thr(int ifrom, int ito, int evflag, int eflag,
+                            int vflag_atom, double *pv1, ThrData * const thr)
+{
+  int i,j,k,m,ii,jj,kk,mm,jnum,itype,jtype,ktype,mtype;
+  tagint itag,jtag;
+  int atomi,atomj,atomk,atomm;
+  int testpath,npath,done;
+  double evdwl,fpair,xtmp,ytmp,ztmp;
+  double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj;
+  double delij[3],rijsq,delik[3],rik,deljk[3];
+  double rkj,wkj,dC,VLJ,dVLJ,VA,Str,dStr,Stb;
+  double vdw,slw,dvdw,dslw,drij,swidth,tee,tee2;
+  double rljmin,rljmax,sigcut,sigmin,sigwid;
+  double delkm[3],rkm,deljm[3],rmj,wmj,r2inv,r6inv,scale,delscale[3];
+  int *ilist,*jlist,*numneigh,**firstneigh;
+  int *REBO_neighs_i,*REBO_neighs_k;
+  double delikS[3],deljkS[3],delkmS[3],deljmS[3],delimS[3];
+  double rikS,rkjS,rkmS,rmjS,wikS,dwikS;
+  double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS;
+  double fpair1,fpair2,fpair3;
+  double fi[3],fj[3],fk[3],fm[3];
 
-      dcosijldri[0] = (-rjl[0]*invrijlm) - (cosijl*rij[0]*invrijm2);
-      dcosijldri[1] = (-rjl[1]*invrijlm) - (cosijl*rij[1]*invrijm2);
-      dcosijldri[2] = (-rjl[2]*invrijlm) - (cosijl*rij[2]*invrijm2);
-      dcosijldrj[0] = ((-rij[0]+rjl[0])*invrijlm) +
-        (cosijl*((rij[0]*invrijm2)-(rjl[0]*invrjlm2)));
-      dcosijldrj[1] = ((-rij[1]+rjl[1])*invrijlm) +
-        (cosijl*((rij[1]*invrijm2)-(rjl[1]*invrjlm2)));
-      dcosijldrj[2] = ((-rij[2]+rjl[2])*invrijlm) +
-        (cosijl*((rij[2]*invrijm2)-(rjl[2]*invrjlm2)));
-      dcosijldrl[0] = (rij[0]*invrijlm)+(cosijl*rjl[0]*invrjlm2);
-      dcosijldrl[1] = (rij[1]*invrijlm)+(cosijl*rjl[1]*invrjlm2);
-      dcosijldrl[2] = (rij[2]*invrijlm)+(cosijl*rjl[2]*invrjlm2);
+  // I-J interaction from full neighbor list
+  // skip 1/2 of interactions since only consider each pair once
 
-      // evaluate splines g and derivatives dg
+  evdwl = 0.0;
+  rljmin = 0.0;
+  rljmax = 0.0;
+  sigcut = 0.0;
+  sigmin = 0.0;
+  sigwid = 0.0;
 
-      g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
-      tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
-      fi[0] = -tmp2*dcosijldri[0];
-      fi[1] = -tmp2*dcosijldri[1];
-      fi[2] = -tmp2*dcosijldri[2];
-      fj[0] = -tmp2*dcosijldrj[0];
-      fj[1] = -tmp2*dcosijldrj[1];
-      fj[2] = -tmp2*dcosijldrj[2];
-      fl[0] = -tmp2*dcosijldrl[0];
-      fl[1] = -tmp2*dcosijldrl[1];
-      fl[2] = -tmp2*dcosijldrl[2];
+  const double * const * const x = atom->x;
+  double * const * const f = thr->get_f();
+  tagint *tag = atom->tag;
+  int *type = atom->type;
+  int nlocal = atom->nlocal;
 
-      tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
-      fi[0] -= tmp2*(rij[0]*invrijm);
-      fi[1] -= tmp2*(rij[1]*invrijm);
-      fi[2] -= tmp2*(rij[2]*invrijm);
-      fj[0] -= tmp2*((-rjl[0]*invrjlm)-(rij[0]*invrijm));
-      fj[1] -= tmp2*((-rjl[1]*invrjlm)-(rij[1]*invrijm));
-      fj[2] -= tmp2*((-rjl[2]*invrjlm)-(rij[2]*invrijm));
-      fl[0] -= tmp2*(rjl[0]*invrjlm);
-      fl[1] -= tmp2*(rjl[1]*invrjlm);
-      fl[2] -= tmp2*(rjl[2]*invrjlm);
+  ilist = list->ilist;
+  numneigh = list->numneigh;
+  firstneigh = list->firstneigh;
 
-      // coordination forces
+  // loop over neighbors of my atoms
 
-      // dwik forces
+  for (ii = ifrom; ii < ito; ii++) {
+    i = ilist[ii];
+    itag = tag[i];
+    itype = map[type[i]];
+    atomi = i;
+    xtmp = x[i][0];
+    ytmp = x[i][1];
+    ztmp = x[i][2];
+    jlist = firstneigh[i];
+    jnum = numneigh[i];
 
-      tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))*invrjlm;
-      fj[0] -= tmp2*rjl[0];
-      fj[1] -= tmp2*rjl[1];
-      fj[2] -= tmp2*rjl[2];
-      fl[0] += tmp2*rjl[0];
-      fl[1] += tmp2*rjl[1];
-      fl[2] += tmp2*rjl[2];
+    for (jj = 0; jj < jnum; jj++) {
+      j = jlist[jj];
+      j &= NEIGHMASK;
+      jtag = tag[j];
 
-      // PIJ forces
+      if (itag > jtag) {
+        if ((itag+jtag) % 2 == 0) continue;
+      } else if (itag < jtag) {
+        if ((itag+jtag) % 2 == 1) continue;
+      } else {
+        if (x[j][2] < ztmp) continue;
+        if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+        if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+      }
 
-      tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)*invrjlm;
-      fj[0] -= tmp2*rjl[0];
-      fj[1] -= tmp2*rjl[1];
-      fj[2] -= tmp2*rjl[2];
-      fl[0] += tmp2*rjl[0];
-      fl[1] += tmp2*rjl[1];
-      fl[2] += tmp2*rjl[2];
+      jtype = map[type[j]];
+      atomj = j;
 
-      // dgdN forces
+      delij[0] = xtmp - x[j][0];
+      delij[1] = ytmp - x[j][1];
+      delij[2] = ztmp - x[j][2];
+      rijsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2];
 
-      tmp2 = VA*.5*(tmp*tmp3*dwjl)*invrjlm;
-      fj[0] -= tmp2*rjl[0];
-      fj[1] -= tmp2*rjl[1];
-      fj[2] -= tmp2*rjl[2];
-      fl[0] += tmp2*rjl[0];
-      fl[1] += tmp2*rjl[1];
-      fl[2] += tmp2*rjl[2];
-
-      f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
-      f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
-      f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
+      // if outside of LJ cutoff, skip
+      // if outside of 4-path cutoff, best = 0.0, no need to test paths
+      // if outside of 2-path cutoff but inside 4-path cutoff,
+      //   best = 0.0, test 3-,4-paths
+      // if inside 2-path cutoff, best = wij, only test 3-,4-paths if best < 1
+      npath = testpath = done = 0;
+      best = 0.0;
 
-      if (vflag_atom) {
-        rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
-        v_tally3_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr);
+      if (rijsq >= cutljsq[itype][jtype]) continue;
+      rij = sqrt(rijsq);
+      if (rij >= cut3rebo) {
+        best = 0.0;
+        testpath = 0;
+      } else if (rij >= rcmax[itype][jtype]) {
+        best = 0.0;
+        testpath = 1;
+      } else {
+        best = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+        npath = 2;
+        if (best < 1.0) testpath = 1;
+        else testpath = 0;
       }
-    }
-  }
-
-  // evaluate Nij conj
-
-  Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
-  piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3);
-
-  // piRC forces
 
-  REBO_neighs_i = REBO_firstneigh[i];
-  for (k = 0; k < REBO_numneigh[i]; k++) {
-    atomk = REBO_neighs_i[k];
-    if (atomk !=atomj) {
-      ktype = map[type[atomk]];
-      rik[0] = x[atomi][0]-x[atomk][0];
-      rik[1] = x[atomi][1]-x[atomk][1];
-      rik[2] = x[atomi][2]-x[atomk][2];
-      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
-      Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
-        (wik*kronecker(itype,1));
-      SpN = Sp(Nki,Nmin,Nmax,dNki);
+      if (testpath) {
 
-      tmp2 = VA*dN3[0]*dwik/rikmag;
-      f[atomi][0] -= tmp2*rik[0];
-      f[atomi][1] -= tmp2*rik[1];
-      f[atomi][2] -= tmp2*rik[2];
-      f[atomk][0] += tmp2*rik[0];
-      f[atomk][1] += tmp2*rik[1];
-      f[atomk][2] += tmp2*rik[2];
+        // test all 3-body paths = I-K-J
+        // I-K interactions come from atom I's REBO neighbors
+        // if wik > current best, compute wkj
+        // if best = 1.0, done
 
-      if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+        REBO_neighs_i = REBO_firstneigh[i];
+        for (kk = 0; kk < REBO_numneigh[i] && done==0; kk++) {
+          k = REBO_neighs_i[kk];
+          if (k == j) continue;
+          ktype = map[type[k]];
 
-      tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
-      f[atomi][0] -= tmp2*rik[0];
-      f[atomi][1] -= tmp2*rik[1];
-      f[atomi][2] -= tmp2*rik[2];
-      f[atomk][0] += tmp2*rik[0];
-      f[atomk][1] += tmp2*rik[1];
-      f[atomk][2] += tmp2*rik[2];
+          delik[0] = x[i][0] - x[k][0];
+          delik[1] = x[i][1] - x[k][1];
+          delik[2] = x[i][2] - x[k][2];
+          rsq = delik[0]*delik[0] + delik[1]*delik[1] + delik[2]*delik[2];
+          if (rsq < rcmaxsq[itype][ktype]) {
+            rik = sqrt(rsq);
+            wik = Sp(rik,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+          } else { dwik = wik = 0.0; rikS = rik = 1.0; }
 
-      if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+          if (wik > best) {
+            deljk[0] = x[j][0] - x[k][0];
+            deljk[1] = x[j][1] - x[k][1];
+            deljk[2] = x[j][2] - x[k][2];
+            rsq = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
+            if (rsq < rcmaxsq[ktype][jtype]) {
+              rkj = sqrt(rsq);
+              wkj = Sp(rkj,rcmin[ktype][jtype],rcmax[ktype][jtype],dwkj);
+              if (wik*wkj > best) {
+                best = wik*wkj;
+                npath = 3;
+                atomk = k;
+                delikS[0] = delik[0];
+                delikS[1] = delik[1];
+                delikS[2] = delik[2];
+                rikS = rik;
+                wikS = wik;
+                dwikS = dwik;
+                deljkS[0] = deljk[0];
+                deljkS[1] = deljk[1];
+                deljkS[2] = deljk[2];
+                rkjS = rkj;
+                wkjS = wkj;
+                dwkjS = dwkj;
+                if (best == 1.0) {
+                  done = 1;
+                  break;
+                }
+              }
+            }
 
-      if (fabs(dNki) > TOL) {
-        REBO_neighs_k = REBO_firstneigh[atomk];
-        for (n = 0; n < REBO_numneigh[atomk]; n++) {
-          atomn = REBO_neighs_k[n];
-          if (atomn != atomi) {
-            ntype = map[type[atomn]];
-            rkn[0] = x[atomk][0]-x[atomn][0];
-            rkn[1] = x[atomk][1]-x[atomn][1];
-            rkn[2] = x[atomk][2]-x[atomn][2];
-            rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
-            Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
+            // test all 4-body paths = I-K-M-J
+            // K-M interactions come from atom K's REBO neighbors
+            // if wik*wkm > current best, compute wmj
+            // if best = 1.0, done
 
-            tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
-            f[atomk][0] -= tmp2*rkn[0];
-            f[atomk][1] -= tmp2*rkn[1];
-            f[atomk][2] -= tmp2*rkn[2];
-            f[atomn][0] += tmp2*rkn[0];
-            f[atomn][1] += tmp2*rkn[1];
-            f[atomn][2] += tmp2*rkn[2];
+            REBO_neighs_k = REBO_firstneigh[k];
+            for (mm = 0; mm < REBO_numneigh[k] && done==0; mm++) {
+              m = REBO_neighs_k[mm];
+              if (m == i || m == j) continue;
+              mtype = map[type[m]];
+              delkm[0] = x[k][0] - x[m][0];
+              delkm[1] = x[k][1] - x[m][1];
+              delkm[2] = x[k][2] - x[m][2];
+              rsq = delkm[0]*delkm[0] + delkm[1]*delkm[1] + delkm[2]*delkm[2];
+              if (rsq < rcmaxsq[ktype][mtype]) {
+                rkm = sqrt(rsq);
+                wkm = Sp(rkm,rcmin[ktype][mtype],rcmax[ktype][mtype],dwkm);
+              } else { dwkm = wkm = 0.0; rkmS = rkm = 1.0; }
 
-            if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
+              if (wik*wkm > best) {
+                deljm[0] = x[j][0] - x[m][0];
+                deljm[1] = x[j][1] - x[m][1];
+                deljm[2] = x[j][2] - x[m][2];
+                rsq = deljm[0]*deljm[0] + deljm[1]*deljm[1] +
+                  deljm[2]*deljm[2];
+                if (rsq < rcmaxsq[mtype][jtype]) {
+                  rmj = sqrt(rsq);
+                  wmj = Sp(rmj,rcmin[mtype][jtype],rcmax[mtype][jtype],dwmj);
+                  if (wik*wkm*wmj > best) {
+                    best = wik*wkm*wmj;
+                    npath = 4;
+                    atomk = k;
+                    delikS[0] = delik[0];
+                    delikS[1] = delik[1];
+                    delikS[2] = delik[2];
+                    rikS = rik;
+                    wikS = wik;
+                    dwikS = dwik;
+                    atomm = m;
+                    delkmS[0] = delkm[0];
+                    delkmS[1] = delkm[1];
+                    delkmS[2] = delkm[2];
+                    rkmS = rkm;
+                    wkmS = wkm;
+                    dwkmS = dwkm;
+                    deljmS[0] = deljm[0];
+                    deljmS[1] = deljm[1];
+                    deljmS[2] = deljm[2];
+                    rmjS = rmj;
+                    wmjS = wmj;
+                    dwmjS = dwmj;
+                    if (best == 1.0) {
+                      done = 1;
+                      break;
+                    }
+                  }
+                }
+              }
+            }
           }
         }
       }
-    }
-  }
-
-  // piRC forces
 
-  REBO_neighs = REBO_firstneigh[atomj];
-  for (l = 0; l < REBO_numneigh[atomj]; l++) {
-    atoml = REBO_neighs[l];
-    if (atoml !=atomi) {
-      ltype = map[type[atoml]];
-      rjl[0] = x[atomj][0]-x[atoml][0];
-      rjl[1] = x[atomj][1]-x[atoml][1];
-      rjl[2] = x[atomj][2]-x[atoml][2];
-      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
-      Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
-        (wjl*kronecker(jtype,1));
-      SpN = Sp(Nlj,Nmin,Nmax,dNlj);
+      cij = 1.0 - best;
+      if (cij == 0.0) continue;
 
-      tmp2 = VA*dN3[1]*dwjl/rjlmag;
-      f[atomj][0] -= tmp2*rjl[0];
-      f[atomj][1] -= tmp2*rjl[1];
-      f[atomj][2] -= tmp2*rjl[2];
-      f[atoml][0] += tmp2*rjl[0];
-      f[atoml][1] += tmp2*rjl[1];
-      f[atoml][2] += tmp2*rjl[2];
+      // compute LJ forces and energy
 
-      if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+      sigwid = 0.84;
+      sigcut = 3.0;
+      sigmin = sigcut - sigwid;
 
-      tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
-      f[atomj][0] -= tmp2*rjl[0];
-      f[atomj][1] -= tmp2*rjl[1];
-      f[atomj][2] -= tmp2*rjl[2];
-      f[atoml][0] += tmp2*rjl[0];
-      f[atoml][1] += tmp2*rjl[1];
-      f[atoml][2] += tmp2*rjl[2];
+      rljmin = sigma[itype][jtype];
+      rljmax = sigcut * rljmin;
+      rljmin = sigmin * rljmin;
 
-      if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+      if (rij > rljmax) {
+        slw = 0.0;
+        dslw = 0.0;
+      } else if (rij > rljmin) {
+        drij = rij - rljmin;
+        swidth = rljmax - rljmin;
+        tee = drij / swidth;
+        tee2 = tee*tee;
+        slw = 1.0 - tee2 * (3.0 - 2.0 * tee);
+        dslw = -6.0 * tee * (1.0 - tee) / swidth;
+      } else {
+        slw = 1.0;
+        dslw = 0.0;
+      }
 
-      if (fabs(dNlj) > TOL) {
-        REBO_neighs_l = REBO_firstneigh[atoml];
-        for (n = 0; n < REBO_numneigh[atoml]; n++) {
-          atomn = REBO_neighs_l[n];
-          if (atomn != atomj) {
-            ntype = map[type[atomn]];
-            rln[0] = x[atoml][0]-x[atomn][0];
-            rln[1] = x[atoml][1]-x[atomn][1];
-            rln[2] = x[atoml][2]-x[atomn][2];
-            rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
-            Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
+      if (morseflag) {
 
-            tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
-            f[atoml][0] -= tmp2*rln[0];
-            f[atoml][1] -= tmp2*rln[1];
-            f[atoml][2] -= tmp2*rln[2];
-            f[atomn][0] += tmp2*rln[0];
-            f[atomn][1] += tmp2*rln[1];
-            f[atomn][2] += tmp2*rln[2];
-
-            if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
-          }
-        }
-      }
-    }
-  }
-
-  Tij = 0.0;
-  dN3[0] = 0.0;
-  dN3[1] = 0.0;
-  dN3[2] = 0.0;
-  if (itype == 0 && jtype == 0)
-    Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3);
-  Etmp = 0.0;
+        const double exr = exp(-rij*lj4[itype][jtype]);
+        vdw = lj1[itype][jtype]*exr*(lj2[itype][jtype]*exr - 2);
+        dvdw = lj3[itype][jtype]*exr*(1-lj2[itype][jtype]*exr);
 
-  if (fabs(Tij) > TOL) {
-    atom2 = atomi;
-    atom3 = atomj;
-    r32[0] = x[atom3][0]-x[atom2][0];
-    r32[1] = x[atom3][1]-x[atom2][1];
-    r32[2] = x[atom3][2]-x[atom2][2];
-    r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
-    r23[0] = -r32[0];
-    r23[1] = -r32[1];
-    r23[2] = -r32[2];
-    r23mag = r32mag;
-    REBO_neighs_i = REBO_firstneigh[i];
-    for (k = 0; k < REBO_numneigh[i]; k++) {
-      atomk = REBO_neighs_i[k];
-      atom1 = atomk;
-      ktype = map[type[atomk]];
-      if (atomk != atomj) {
-        r21[0] = x[atom2][0]-x[atom1][0];
-        r21[1] = x[atom2][1]-x[atom1][1];
-        r21[2] = x[atom2][2]-x[atom1][2];
-        r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
-        cos321 = -1.0*((r21[0]*r32[0])+(r21[1]*r32[1])+(r21[2]*r32[2])) /
-          (r21mag*r32mag);
-        cos321 = MIN(cos321,1.0);
-        cos321 = MAX(cos321,-1.0);
-        Sp2(cos321,thmin,thmax,dcut321);
-        sin321 = sqrt(1.0 - cos321*cos321);
-        if ((sin321 > TOL) && (r21mag > TOL)) { // XXX was sin321 != 0.0
-          sink2i = 1.0/(sin321*sin321);
-          rik2i = 1.0/(r21mag*r21mag);
-          rr = (r23mag*r23mag)-(r21mag*r21mag);
-          rjk[0] = r21[0]-r23[0];
-          rjk[1] = r21[1]-r23[1];
-          rjk[2] = r21[2]-r23[2];
-          rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
-          rijrik = 2.0*r23mag*r21mag;
-          rik2 = r21mag*r21mag;
-          dctik = (-rr+rjk2)/(rijrik*rik2);
-          dctij = (rr+rjk2)/(rijrik*r23mag*r23mag);
-          dctjk = -2.0/rijrik;
-          w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
-          rijmag = r32mag;
-          rikmag = r21mag;
-          rij2 = r32mag*r32mag;
-          rik2 = r21mag*r21mag;
-          costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
-          tspjik = Sp2(costmp,thmin,thmax,dtsjik);
-          dtsjik = -dtsjik;
+      } else {
 
-          REBO_neighs_j = REBO_firstneigh[j];
-          for (l = 0; l < REBO_numneigh[j]; l++) {
-            atoml = REBO_neighs_j[l];
-            atom4 = atoml;
-            ltype = map[type[atoml]];
-            if (!(atoml == atomi || atoml == atomk)) {
-              r34[0] = x[atom3][0]-x[atom4][0];
-              r34[1] = x[atom3][1]-x[atom4][1];
-              r34[2] = x[atom3][2]-x[atom4][2];
-              r34mag = sqrt((r34[0]*r34[0])+(r34[1]*r34[1])+(r34[2]*r34[2]));
-              cos234 = (r32[0]*r34[0] + r32[1]*r34[1] + r32[2]*r34[2]) /
-                (r32mag*r34mag);
-              cos234 = MIN(cos234,1.0);
-              cos234 = MAX(cos234,-1.0);
-              sin234 = sqrt(1.0 - cos234*cos234);
+        r2inv = 1.0/rijsq;
+        r6inv = r2inv*r2inv*r2inv;
 
-              if ((sin234 > TOL) && (r34mag > TOL)) {  // XXX was sin234 != 0.0
-                sinl2i = 1.0/(sin234*sin234);
-                rjl2i = 1.0/(r34mag*r34mag);
-                w34 = Sp(r34mag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dw34);
-                rr = (r23mag*r23mag)-(r34mag*r34mag);
-                ril[0] = r23[0]+r34[0];
-                ril[1] = r23[1]+r34[1];
-                ril[2] = r23[2]+r34[2];
-                ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
-                rijrjl = 2.0*r23mag*r34mag;
-                rjl2 = r34mag*r34mag;
-                dctjl = (-rr+ril2)/(rijrjl*rjl2);
-                dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
-                dctil = -2.0/rijrjl;
-                rjlmag = r34mag;
-                rjl2 = r34mag*r34mag;
-                costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
-                tspijl = Sp2(costmp,thmin,thmax,dtsijl);
-                dtsijl = -dtsijl;
-                prefactor = VA*Tij;
+        vdw = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
+        dvdw = -r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) / rij;
+      }
 
-                cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
-                cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
-                cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
-                cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
-                cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
-                cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
+      // VLJ now becomes vdw * slw, derivaties, etc.
 
-                cwnum = (cross321[0]*cross234[0]) +
-                  (cross321[1]*cross234[1]) + (cross321[2]*cross234[2]);
-                cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
-                om1234 = cwnum/cwnom;
-                cw = om1234;
-                Etmp += ((1.0-square(om1234))*w21*w34) *
-                  (1.0-tspjik)*(1.0-tspijl);
+      VLJ = vdw * slw;
+      dVLJ = dvdw * slw + vdw * dslw;
 
-                dt1dik = (rik2i)-(dctik*sink2i*cos321);
-                dt1djk = (-dctjk*sink2i*cos321);
-                dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
-                dt1dil = (-dctil*sinl2i*cos234);
-                dt1dij = (2.0/(r23mag*r23mag))-(dctij*sink2i*cos321) -
-                  (dctji*sinl2i*cos234);
+      Str = Sp2(rij,rcLJmin[itype][jtype],rcLJmax[itype][jtype],dStr);
+      VA = Str*cij*VLJ;
+      if (Str > 0.0) {
+        scale = rcmin[itype][jtype] / rij;
+        delscale[0] = scale * delij[0];
+        delscale[1] = scale * delij[1];
+        delscale[2] = scale * delij[2];
+        Stb = bondorderLJ_thr(i,j,delscale,rcmin[itype][jtype],VA,
+                              delij,rij,vflag_atom,thr);
+      } else Stb = 0.0;
 
-                dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
-                dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
-                dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
+      fpair = -(dStr * (Stb*cij*VLJ - cij*VLJ) +
+                dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij;
 
-                dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
-                dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
-                dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
+      f[i][0] += delij[0]*fpair;
+      f[i][1] += delij[1]*fpair;
+      f[i][2] += delij[2]*fpair;
+      f[j][0] -= delij[0]*fpair;
+      f[j][1] -= delij[1]*fpair;
+      f[j][2] -= delij[2]*fpair;
 
-                dt2dij[0] = (r21[2]*cross234[1])-(r34[2]*cross321[1]) -
-                  (r21[1]*cross234[2])+(r34[1]*cross321[2]);
-                dt2dij[1] = (r21[0]*cross234[2])-(r34[0]*cross321[2]) -
-                  (r21[2]*cross234[0])+(r34[2]*cross321[0]);
-                dt2dij[2] = (r21[1]*cross234[0])-(r34[1]*cross321[0]) -
-                  (r21[0]*cross234[1])+(r34[0]*cross321[1]);
+      if (eflag) *pv1 += evdwl = VA*Stb + (1.0-Str)*cij*VLJ;
+      if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
+                               evdwl,0.0,fpair,delij[0],delij[1],delij[2],thr);
 
-                aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
-                  (1.0-tspjik)*(1.0-tspijl);
-                aaa1 = -prefactor*(1.0-square(om1234)) *
-                  (1.0-tspjik)*(1.0-tspijl);
-                aaa2 = aaa1*w21*w34;
-                at2 = aa*cwnum;
+      if (cij < 1.0) {
+        dC = Str*Stb*VLJ + (1.0-Str)*VLJ;
+        if (npath == 2) {
+          fpair = dC*dwij / rij;
+          f[atomi][0] += delij[0]*fpair;
+          f[atomi][1] += delij[1]*fpair;
+          f[atomi][2] += delij[2]*fpair;
+          f[atomj][0] -= delij[0]*fpair;
+          f[atomj][1] -= delij[1]*fpair;
+          f[atomj][2] -= delij[2]*fpair;
 
-                fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
-                  (aaa2*dtsijl*dctji*(1.0-tspjik));
-                fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
-                fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
-                fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
-                fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
+          if (vflag_atom) v_tally2_thr(atomi,atomj,fpair,delij,thr);
 
-                F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
-                F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
-                F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
+        } else if (npath == 3) {
+          fpair1 = dC*dwikS*wkjS / rikS;
+          fi[0] = delikS[0]*fpair1;
+          fi[1] = delikS[1]*fpair1;
+          fi[2] = delikS[2]*fpair1;
+          fpair2 = dC*wikS*dwkjS / rkjS;
+          fj[0] = deljkS[0]*fpair2;
+          fj[1] = deljkS[1]*fpair2;
+          fj[2] = deljkS[2]*fpair2;
 
-                F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
-                F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
-                F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
+          f[atomi][0] += fi[0];
+          f[atomi][1] += fi[1];
+          f[atomi][2] += fi[2];
+          f[atomj][0] += fj[0];
+          f[atomj][1] += fj[1];
+          f[atomj][2] += fj[2];
+          f[atomk][0] -= fi[0] + fj[0];
+          f[atomk][1] -= fi[1] + fj[1];
+          f[atomk][2] -= fi[2] + fj[2];
 
-                F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
-                F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
-                F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
+          if (vflag_atom)
+            v_tally3_thr(atomi,atomj,atomk,fi,fj,delikS,deljkS,thr);
 
-                F31[0] = (fcjkpc*rjk[0]);
-                F31[1] = (fcjkpc*rjk[1]);
-                F31[2] = (fcjkpc*rjk[2]);
+        } else if (npath == 4) {
+          fpair1 = dC*dwikS*wkmS*wmjS / rikS;
+          fi[0] = delikS[0]*fpair1;
+          fi[1] = delikS[1]*fpair1;
+          fi[2] = delikS[2]*fpair1;
 
-                F24[0] = (fcilpc*ril[0]);
-                F24[1] = (fcilpc*ril[1]);
-                F24[2] = (fcilpc*ril[2]);
+          fpair2 = dC*wikS*dwkmS*wmjS / rkmS;
+          fk[0] = delkmS[0]*fpair2 - fi[0];
+          fk[1] = delkmS[1]*fpair2 - fi[1];
+          fk[2] = delkmS[2]*fpair2 - fi[2];
 
-                f1[0] = -F12[0]-F31[0];
-                f1[1] = -F12[1]-F31[1];
-                f1[2] = -F12[2]-F31[2];
-                f2[0] = F23[0]+F12[0]+F24[0];
-                f2[1] = F23[1]+F12[1]+F24[1];
-                f2[2] = F23[2]+F12[2]+F24[2];
-                f3[0] = -F23[0]+F34[0]+F31[0];
-                f3[1] = -F23[1]+F34[1]+F31[1];
-                f3[2] = -F23[2]+F34[2]+F31[2];
-                f4[0] = -F34[0]-F24[0];
-                f4[1] = -F34[1]-F24[1];
-                f4[2] = -F34[2]-F24[2];
+          fpair3 = dC*wikS*wkmS*dwmjS / rmjS;
+          fj[0] = deljmS[0]*fpair3;
+          fj[1] = deljmS[1]*fpair3;
+          fj[2] = deljmS[2]*fpair3;
 
-                // coordination forces
+          fm[0] = -delkmS[0]*fpair2 - fj[0];
+          fm[1] = -delkmS[1]*fpair2 - fj[1];
+          fm[2] = -delkmS[2]*fpair2 - fj[2];
 
-                tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
-                  (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
-                f2[0] -= tmp2*r21[0];
-                f2[1] -= tmp2*r21[1];
-                f2[2] -= tmp2*r21[2];
-                f1[0] += tmp2*r21[0];
-                f1[1] += tmp2*r21[1];
-                f1[2] += tmp2*r21[2];
-
-                tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
-                  (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
-                f3[0] -= tmp2*r34[0];
-                f3[1] -= tmp2*r34[1];
-                f3[2] -= tmp2*r34[2];
-                f4[0] += tmp2*r34[0];
-                f4[1] += tmp2*r34[1];
-                f4[2] += tmp2*r34[2];
-
-                f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
-                f[atom1][2] += f1[2];
-                f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
-                f[atom2][2] += f2[2];
-                f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
-                f[atom3][2] += f3[2];
-                f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
-                f[atom4][2] += f4[2];
+          f[atomi][0] += fi[0];
+          f[atomi][1] += fi[1];
+          f[atomi][2] += fi[2];
+          f[atomj][0] += fj[0];
+          f[atomj][1] += fj[1];
+          f[atomj][2] += fj[2];
+          f[atomk][0] += fk[0];
+          f[atomk][1] += fk[1];
+          f[atomk][2] += fk[2];
+          f[atomm][0] += fm[0];
+          f[atomm][1] += fm[1];
+          f[atomm][2] += fm[2];
 
-                if (vflag_atom) {
-                  r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
-                  r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
-                  v_tally4_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr);
-                }
-              }
-            }
+          if (vflag_atom) {
+            delimS[0] = delikS[0] + delkmS[0];
+            delimS[1] = delikS[1] + delkmS[1];
+            delimS[2] = delikS[2] + delkmS[2];
+            v_tally4_thr(atomi,atomj,atomk,atomm,fi,fj,fk,delimS,deljmS,delkmS,thr);
           }
         }
       }
     }
+  }
+}
 
-    // Tij forces now that we have Etmp
-
-    REBO_neighs = REBO_firstneigh[i];
-    for (k = 0; k < REBO_numneigh[i]; k++) {
-      atomk = REBO_neighs[k];
-      if (atomk != atomj) {
-        ktype = map[type[atomk]];
-        rik[0] = x[atomi][0]-x[atomk][0];
-        rik[1] = x[atomi][1]-x[atomk][1];
-        rik[2] = x[atomi][2]-x[atomk][2];
-        rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-        wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
-        Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
-          (wik*kronecker(itype,1));
-        SpN = Sp(Nki,Nmin,Nmax,dNki);
-
-        tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
-        f[atomi][0] -= tmp2*rik[0];
-        f[atomi][1] -= tmp2*rik[1];
-        f[atomi][2] -= tmp2*rik[2];
-        f[atomk][0] += tmp2*rik[0];
-        f[atomk][1] += tmp2*rik[1];
-        f[atomk][2] += tmp2*rik[2];
+/* ----------------------------------------------------------------------
+   torsional forces and energy
+------------------------------------------------------------------------- */
 
-        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+void PairAIREBOOMP::TORSION_thr(int ifrom, int ito, int evflag, int eflag,
+                                double *pv2, ThrData * const thr)
+{
+  int i,j,k,l,ii;
+  tagint itag,jtag;
+  double evdwl,fpair,xtmp,ytmp,ztmp;
+  double cos321;
+  double w21,dw21,cos234,w34,dw34;
+  double cross321[3],cross321mag,cross234[3],cross234mag;
+  double w23,dw23,cw2,ekijl,Ec;
+  double cw,cwnum,cwnom;
+  double rij,rij2,rik,rjl,tspjik,dtsjik,tspijl,dtsijl,costmp,fcpc;
+  double sin321,sin234,rjk2,rik2,ril2,rjl2;
+  double rjk,ril;
+  double Vtors;
+  double dndij[3],tmpvec[3],dndik[3],dndjl[3];
+  double dcidij,dcidik,dcidjk,dcjdji,dcjdjl,dcjdil;
+  double dsidij,dsidik,dsidjk,dsjdji,dsjdjl,dsjdil;
+  double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil;
+  double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3];
+  double del32[3],rsq,r32,del23[3],del21[3],r21;
+  double deljk[3],del34[3],delil[3],delkl[3],r23,r34;
+  double fi[3],fj[3],fk[3],fl[3];
+  int itype,jtype,ktype,ltype,kk,ll,jj;
+  int *ilist,*REBO_neighs_i,*REBO_neighs_j;
 
-        tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
-        f[atomi][0] -= tmp2*rik[0];
-        f[atomi][1] -= tmp2*rik[1];
-        f[atomi][2] -= tmp2*rik[2];
-        f[atomk][0] += tmp2*rik[0];
-        f[atomk][1] += tmp2*rik[1];
-        f[atomk][2] += tmp2*rik[2];
+  const double * const * const x = atom->x;
+  double * const * const f = thr->get_f();
+  int *type = atom->type;
+  tagint *tag = atom->tag;
 
-        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+  ilist = list->ilist;
 
-        if (fabs(dNki) > TOL) {
-          REBO_neighs_k = REBO_firstneigh[atomk];
-          for (n = 0; n < REBO_numneigh[atomk]; n++) {
-            atomn = REBO_neighs_k[n];
-            ntype = map[type[atomn]];
-            if (atomn != atomi) {
-              rkn[0] = x[atomk][0]-x[atomn][0];
-              rkn[1] = x[atomk][1]-x[atomn][1];
-              rkn[2] = x[atomk][2]-x[atomn][2];
-              rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
-              Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
+  for (ii = ifrom; ii < ito; ii++) {
+    i = ilist[ii];
+    itag = tag[i];
+    itype = map[type[i]];
+    if (itype != 0) continue;
+    xtmp = x[i][0];
+    ytmp = x[i][1];
+    ztmp = x[i][2];
+    REBO_neighs_i = REBO_firstneigh[i];
 
-              tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
-              f[atomk][0] -= tmp2*rkn[0];
-              f[atomk][1] -= tmp2*rkn[1];
-              f[atomk][2] -= tmp2*rkn[2];
-              f[atomn][0] += tmp2*rkn[0];
-              f[atomn][1] += tmp2*rkn[1];
-              f[atomn][2] += tmp2*rkn[2];
+    for (jj = 0; jj < REBO_numneigh[i]; jj++) {
+      j = REBO_neighs_i[jj];
+      jtag = tag[j];
 
-              if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
-            }
-          }
-        }
+      if (itag > jtag) {
+        if ((itag+jtag) % 2 == 0) continue;
+      } else if (itag < jtag) {
+        if ((itag+jtag) % 2 == 1) continue;
+      } else {
+        if (x[j][2] < ztmp) continue;
+        if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
+        if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
       }
-    }
 
-    // Tij forces
+      jtype = map[type[j]];
+      if (jtype != 0) continue;
 
-    REBO_neighs = REBO_firstneigh[j];
-    for (l = 0; l < REBO_numneigh[j]; l++) {
-      atoml = REBO_neighs[l];
-      if (atoml != atomi) {
-        ltype = map[type[atoml]];
-        rjl[0] = x[atomj][0]-x[atoml][0];
-        rjl[1] = x[atomj][1]-x[atoml][1];
-        rjl[2] = x[atomj][2]-x[atoml][2];
-        rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-        wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
-        Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
-          (wjl*kronecker(jtype,1));
-        SpN = Sp(Nlj,Nmin,Nmax,dNlj);
+      del32[0] = x[j][0]-x[i][0];
+      del32[1] = x[j][1]-x[i][1];
+      del32[2] = x[j][2]-x[i][2];
+      rsq = del32[0]*del32[0] + del32[1]*del32[1] + del32[2]*del32[2];
+      r32 = sqrt(rsq);
+      del23[0] = -del32[0];
+      del23[1] = -del32[1];
+      del23[2] = -del32[2];
+      r23 = r32;
+      w23 = Sp(r23,rcmin[itype][jtype],rcmax[itype][jtype],dw23);
 
-        tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
-        f[atomj][0] -= tmp2*rjl[0];
-        f[atomj][1] -= tmp2*rjl[1];
-        f[atomj][2] -= tmp2*rjl[2];
-        f[atoml][0] += tmp2*rjl[0];
-        f[atoml][1] += tmp2*rjl[1];
-        f[atoml][2] += tmp2*rjl[2];
+      for (kk = 0; kk < REBO_numneigh[i]; kk++) {
+        k = REBO_neighs_i[kk];
+        ktype = map[type[k]];
+        if (k == j) continue;
+        del21[0] = x[i][0]-x[k][0];
+        del21[1] = x[i][1]-x[k][1];
+        del21[2] = x[i][2]-x[k][2];
+        rsq = del21[0]*del21[0] + del21[1]*del21[1] + del21[2]*del21[2];
+        r21 = sqrt(rsq);
+        cos321 = - ((del21[0]*del32[0]) + (del21[1]*del32[1]) +
+                    (del21[2]*del32[2])) / (r21*r32);
+        cos321 = MIN(cos321,1.0);
+        cos321 = MAX(cos321,-1.0);
+        sin321 = sqrt(1.0 - cos321*cos321);
+        if (sin321 < TOL) continue;
 
-        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+        deljk[0] = del21[0]-del23[0];
+        deljk[1] = del21[1]-del23[1];
+        deljk[2] = del21[2]-del23[2];
+        rjk2 = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
+        rjk=sqrt(rjk2);
+        rik2 = r21*r21;
+        w21 = Sp(r21,rcmin[itype][ktype],rcmax[itype][ktype],dw21);
 
-        tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
-        f[atomj][0] -= tmp2*rjl[0];
-        f[atomj][1] -= tmp2*rjl[1];
-        f[atomj][2] -= tmp2*rjl[2];
-        f[atoml][0] += tmp2*rjl[0];
-        f[atoml][1] += tmp2*rjl[1];
-        f[atoml][2] += tmp2*rjl[2];
+        rij = r32;
+        rik = r21;
+        rij2 = r32*r32;
+        rik2 = r21*r21;
+        costmp = 0.5*(rij2+rik2-rjk2)/rij/rik;
+        tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+        dtsjik = -dtsjik;
 
-        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+        REBO_neighs_j = REBO_firstneigh[j];
+        for (ll = 0; ll < REBO_numneigh[j]; ll++) {
+          l = REBO_neighs_j[ll];
+          ltype = map[type[l]];
+          if (l == i || l == k) continue;
+          del34[0] = x[j][0]-x[l][0];
+          del34[1] = x[j][1]-x[l][1];
+          del34[2] = x[j][2]-x[l][2];
+          rsq = del34[0]*del34[0] + del34[1]*del34[1] + del34[2]*del34[2];
+          r34 = sqrt(rsq);
+          cos234 = (del32[0]*del34[0] + del32[1]*del34[1] +
+                    del32[2]*del34[2]) / (r32*r34);
+          cos234 = MIN(cos234,1.0);
+          cos234 = MAX(cos234,-1.0);
+          sin234 = sqrt(1.0 - cos234*cos234);
+          if (sin234 < TOL) continue;
+          w34 = Sp(r34,rcmin[jtype][ltype],rcmax[jtype][ltype],dw34);
+          delil[0] = del23[0] + del34[0];
+          delil[1] = del23[1] + del34[1];
+          delil[2] = del23[2] + del34[2];
+          ril2 = delil[0]*delil[0] + delil[1]*delil[1] + delil[2]*delil[2];
+          ril=sqrt(ril2);
+          rjl2 = r34*r34;
 
-        if (fabs(dNlj) > TOL) {
-          REBO_neighs_l = REBO_firstneigh[atoml];
-          for (n = 0; n < REBO_numneigh[atoml]; n++) {
-            atomn = REBO_neighs_l[n];
-            ntype = map[type[atomn]];
-            if (atomn !=atomj) {
-              rln[0] = x[atoml][0]-x[atomn][0];
-              rln[1] = x[atoml][1]-x[atomn][1];
-              rln[2] = x[atoml][2]-x[atomn][2];
-              rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
-              Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
-
-              tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
-              f[atoml][0] -= tmp2*rln[0];
-              f[atoml][1] -= tmp2*rln[1];
-              f[atoml][2] -= tmp2*rln[2];
-              f[atomn][0] += tmp2*rln[0];
-              f[atomn][1] += tmp2*rln[1];
-              f[atomn][2] += tmp2*rln[2];
+          rjl = r34;
+          rjl2 = r34*r34;
+          costmp = 0.5*(rij2+rjl2-ril2)/rij/rjl;
+          tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+          dtsijl = -dtsijl; //need minus sign
+          cross321[0] = (del32[1]*del21[2])-(del32[2]*del21[1]);
+          cross321[1] = (del32[2]*del21[0])-(del32[0]*del21[2]);
+          cross321[2] = (del32[0]*del21[1])-(del32[1]*del21[0]);
+          cross321mag = sqrt(cross321[0]*cross321[0]+
+                             cross321[1]*cross321[1]+
+                             cross321[2]*cross321[2]);
+          cross234[0] = (del23[1]*del34[2])-(del23[2]*del34[1]);
+          cross234[1] = (del23[2]*del34[0])-(del23[0]*del34[2]);
+          cross234[2] = (del23[0]*del34[1])-(del23[1]*del34[0]);
+          cross234mag = sqrt(cross234[0]*cross234[0]+
+                             cross234[1]*cross234[1]+
+                             cross234[2]*cross234[2]);
+          cwnum = (cross321[0]*cross234[0]) +
+            (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
+          cwnom = r21*r34*r32*r32*sin321*sin234;
+          cw = cwnum/cwnom;
 
-              if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
-            }
-          }
-        }
-      }
-    }
-  }
+          cw2 = (.5*(1.0-cw));
+          ekijl = epsilonT[ktype][ltype];
+          Ec = 256.0*ekijl/405.0;
+          Vtors = (Ec*(powint(cw2,5)))-(ekijl/10.0);
 
-  bij = (0.5*(pij+pji))+piRC+(Tij*Etmp);
-  return bij;
-}
+          if (eflag) *pv2 += evdwl = Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl);
 
-/* ----------------------------------------------------------------------
-   Bij* function
-------------------------------------------------------------------------- */
+          dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]);
+          dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]);
+          dndij[2] = (cross234[0]*del21[1])-(cross234[1]*del21[0]);
 
-double PairAIREBOOMP::bondorderLJ_thr(int i, int j, double rij[3], double rijmag,
-                                      double VA, double rij0[3], double rij0mag,
-                                      int vflag_atom, ThrData * const thr)
-{
-  int k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
-  int atomi,atomj,itype,jtype,ktype,ltype,ntype;
-  double rik[3], rjl[3], rkn[3],rknmag,dNki;
-  double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
-  double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
-  double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ;
-  double Nki,Nlj,dS,lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
-  double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
-  double dN2[2],dN3[3];
-  double dcosijldrj[3],dcosijldrl[3],dcosjikdrj[3],dwjl;
-  double Tij,crosskij[3],crosskijmag;
-  double crossijl[3],crossijlmag,omkijl;
-  double tmppij,tmppji,dN2PIJ[2],dN2PJI[2],dN3piRC[3],dN3Tij[3];
-  double bij,tmp3pij,tmp3pji,Stb,dStb;
-  double r32[3],r32mag,cos321;
-  double om1234,rln[3];
-  double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
-  double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
-  double cross321[3],cross234[3],prefactor,SpN;
-  double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
-  double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
-  double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
-  double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
-  double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
-  double dNlj;
-  double PijS,PjiS;
-  double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
-  int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
-  double F12[3],F23[3],F34[3],F31[3],F24[3];
-  double fi[3],fj[3],fk[3],fl[3],f1[3],f2[3],f3[3],f4[4];
-  double rji[3],rki[3],rlj[3],r13[3],r43[3];
+          tmpvec[0] = (del34[1]*cross321[2])-(del34[2]*cross321[1]);
+          tmpvec[1] = (del34[2]*cross321[0])-(del34[0]*cross321[2]);
+          tmpvec[2] = (del34[0]*cross321[1])-(del34[1]*cross321[0]);
 
-  const double * const * const x = atom->x;
-  double * const * const f = thr->get_f();
-  const int * const type = atom->type;
+          dndij[0] = dndij[0]+tmpvec[0];
+          dndij[1] = dndij[1]+tmpvec[1];
+          dndij[2] = dndij[2]+tmpvec[2];
 
-  atomi = i;
-  atomj = j;
-  itype = map[type[atomi]];
-  jtype = map[type[atomj]];
-  wij = Sp(rij0mag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
-  NijC = nC[atomi]-(wij*kronecker(jtype,0));
-  NijH = nH[atomi]-(wij*kronecker(jtype,1));
-  NjiC = nC[atomj]-(wij*kronecker(itype,0));
-  NjiH = nH[atomj]-(wij*kronecker(itype,1));
+          dndik[0] = (del23[1]*cross234[2])-(del23[2]*cross234[1]);
+          dndik[1] = (del23[2]*cross234[0])-(del23[0]*cross234[2]);
+          dndik[2] = (del23[0]*cross234[1])-(del23[1]*cross234[0]);
 
-  bij = 0.0;
-  tmp = 0.0;
-  tmp2 = 0.0;
-  tmp3 = 0.0;
-  dgdc = 0.0;
-  dgdN = 0.0;
-  NconjtmpI = 0.0;
-  NconjtmpJ = 0.0;
-  Etmp = 0.0;
+          dndjl[0] = (cross321[1]*del23[2])-(cross321[2]*del23[1]);
+          dndjl[1] = (cross321[2]*del23[0])-(cross321[0]*del23[2]);
+          dndjl[2] = (cross321[0]*del23[1])-(cross321[1]*del23[0]);
 
-  REBO_neighs = REBO_firstneigh[i];
-  for (k = 0; k < REBO_numneigh[i]; k++) {
-    atomk = REBO_neighs[k];
-    if (atomk != atomj) {
-      ktype = map[type[atomk]];
-      rik[0] = x[atomi][0]-x[atomk][0];
-      rik[1] = x[atomi][1]-x[atomk][1];
-      rik[2] = x[atomi][2]-x[atomk][2];
-      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-      lamdajik = 4.0*kronecker(itype,1) *
-        ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
-      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
-      Nki = nC[atomk]-(wik*kronecker(itype,0)) +
-        nH[atomk]-(wik*kronecker(itype,1));
-      cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
-        (rijmag*rikmag);
-      cosjik = MIN(cosjik,1.0);
-      cosjik = MAX(cosjik,-1.0);
+          dcidij = ((r23*r23)-(r21*r21)+(rjk*rjk))/(2.0*r23*r23*r21);
+          dcidik = ((r21*r21)-(r23*r23)+(rjk*rjk))/(2.0*r23*r21*r21);
+          dcidjk = (-rjk)/(r23*r21);
+          dcjdji = ((r23*r23)-(r34*r34)+(ril*ril))/(2.0*r23*r23*r34);
+          dcjdjl = ((r34*r34)-(r23*r23)+(ril*ril))/(2.0*r23*r34*r34);
+          dcjdil = (-ril)/(r23*r34);
 
-      // evaluate splines g and derivatives dg
+          dsidij = (-cos321/sin321)*dcidij;
+          dsidik = (-cos321/sin321)*dcidik;
+          dsidjk = (-cos321/sin321)*dcidjk;
 
-      g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
-      Etmp += (wik*g*exp(lamdajik));
-      tmp3 += (wik*dgdN*exp(lamdajik));
-      NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
-    }
-  }
+          dsjdji = (-cos234/sin234)*dcjdji;
+          dsjdjl = (-cos234/sin234)*dcjdjl;
+          dsjdil = (-cos234/sin234)*dcjdil;
 
-  PijS = 0.0;
-  dN2PIJ[0] = 0.0;
-  dN2PIJ[1] = 0.0;
-  PijS = PijSpline(NijC,NijH,itype,jtype,dN2PIJ);
-  pij = 1.0/sqrt(1.0+Etmp+PijS);
-  tmppij = -.5*pij*pij*pij;
-  tmp3pij = tmp3;
-  tmp = 0.0;
-  tmp2 = 0.0;
-  tmp3 = 0.0;
-  Etmp = 0.0;
+          dxidij = (r21*sin321)+(r23*r21*dsidij);
+          dxidik = (r23*sin321)+(r23*r21*dsidik);
+          dxidjk = (r23*r21*dsidjk);
 
-  REBO_neighs = REBO_firstneigh[j];
-  for (l = 0; l < REBO_numneigh[j]; l++) {
-    atoml = REBO_neighs[l];
-    if (atoml != atomi) {
-      ltype = map[type[atoml]];
-      rjl[0] = x[atomj][0]-x[atoml][0];
-      rjl[1] = x[atomj][1]-x[atoml][1];
-      rjl[2] = x[atomj][2]-x[atoml][2];
-      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-      lamdaijl = 4.0*kronecker(jtype,1) *
-        ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
-      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
-      Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
-        (wjl*kronecker(jtype,1));
-      cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
-        (rijmag*rjlmag);
-      cosijl = MIN(cosijl,1.0);
-      cosijl = MAX(cosijl,-1.0);
+          dxjdji = (r34*sin234)+(r23*r34*dsjdji);
+          dxjdjl = (r23*sin234)+(r23*r34*dsjdjl);
+          dxjdil = (r23*r34*dsjdil);
 
-      // evaluate splines g and derivatives dg
+          ddndij = (dxidij*cross234mag)+(cross321mag*dxjdji);
+          ddndik = dxidik*cross234mag;
+          ddndjk = dxidjk*cross234mag;
+          ddndjl = cross321mag*dxjdjl;
+          ddndil = cross321mag*dxjdil;
+          dcwddn = -cwnum/(cwnom*cwnom);
+          dcwdn = 1.0/cwnom;
+          dvpdcw = (-1.0)*Ec*(-.5)*5.0*powint(cw2,4) *
+            w23*w21*w34*(1.0-tspjik)*(1.0-tspijl);
 
-      g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
-      Etmp += (wjl*g*exp(lamdaijl));
-      tmp3 += (wjl*dgdN*exp(lamdaijl));
-      NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
-    }
-  }
+          Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23));
+          Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23));
+          Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23));
+          fi[0] = Ftmp[0];
+          fi[1] = Ftmp[1];
+          fi[2] = Ftmp[2];
+          fj[0] = -Ftmp[0];
+          fj[1] = -Ftmp[1];
+          fj[2] = -Ftmp[2];
 
-  PjiS = 0.0;
-  dN2PJI[0] = 0.0;
-  dN2PJI[1] = 0.0;
-  PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2PJI);
-  pji = 1.0/sqrt(1.0+Etmp+PjiS);
-  tmppji = -.5*pji*pji*pji;
-  tmp3pji = tmp3;
+          Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21));
+          Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21));
+          Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21));
+          fi[0] += Ftmp[0];
+          fi[1] += Ftmp[1];
+          fi[2] += Ftmp[2];
+          fk[0] = -Ftmp[0];
+          fk[1] = -Ftmp[1];
+          fk[2] = -Ftmp[2];
 
-  // evaluate Nij conj
+          Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk;
+          Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk;
+          Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk;
+          fj[0] += Ftmp[0];
+          fj[1] += Ftmp[1];
+          fj[2] += Ftmp[2];
+          fk[0] -= Ftmp[0];
+          fk[1] -= Ftmp[1];
+          fk[2] -= Ftmp[2];
 
-  Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
-  piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3piRC);
-  Tij = 0.0;
-  dN3Tij[0] = 0.0;
-  dN3Tij[1] = 0.0;
-  dN3Tij[2] = 0.0;
-  if (itype == 0 && jtype == 0)
-    Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3Tij);
-
-  Etmp = 0.0;
-  if (fabs(Tij) > TOL) {
-    REBO_neighs_i = REBO_firstneigh[i];
-    for (k = 0; k < REBO_numneigh[i]; k++) {
-      atomk = REBO_neighs_i[k];
-      ktype = map[type[atomk]];
-      if (atomk != atomj) {
-        rik[0] = x[atomi][0]-x[atomk][0];
-        rik[1] = x[atomi][1]-x[atomk][1];
-        rik[2] = x[atomi][2]-x[atomk][2];
-        rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-        cos321 = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
-          (rijmag*rikmag);
-        cos321 = MIN(cos321,1.0);
-        cos321 = MAX(cos321,-1.0);
-
-        rjk[0] = rik[0]-rij[0];
-        rjk[1] = rik[1]-rij[1];
-        rjk[2] = rik[2]-rij[2];
-        rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
-        rij2 = rijmag*rijmag;
-        rik2 = rikmag*rikmag;
-        costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
-        tspjik = Sp2(costmp,thmin,thmax,dtsjik);
-
-        if (sqrt(1.0 - cos321*cos321) > sqrt(TOL)) {
-          wik = Sp(rikmag,rcmin[itype][ktype],rcmaxp[itype][ktype],dwik);
-          REBO_neighs_j = REBO_firstneigh[j];
-          for (l = 0; l < REBO_numneigh[j]; l++) {
-            atoml = REBO_neighs_j[l];
-            ltype = map[type[atoml]];
-            if (!(atoml == atomi || atoml == atomk)) {
-              rjl[0] = x[atomj][0]-x[atoml][0];
-              rjl[1] = x[atomj][1]-x[atoml][1];
-              rjl[2] = x[atomj][2]-x[atoml][2];
-              rjlmag = sqrt(rjl[0]*rjl[0] + rjl[1]*rjl[1] + rjl[2]*rjl[2]);
-              cos234 = -((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
-                (rijmag*rjlmag);
-              cos234 = MIN(cos234,1.0);
-              cos234 = MAX(cos234,-1.0);
-
-              ril[0] = rij[0]+rjl[0];
-              ril[1] = rij[1]+rjl[1];
-              ril[2] = rij[2]+rjl[2];
-              ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
-              rjl2 = rjlmag*rjlmag;
-              costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
-              tspijl = Sp2(costmp,thmin,thmax,dtsijl);
-
-              if (sqrt(1.0 - cos234*cos234) > sqrt(TOL)) {
-                wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dS);
-                crosskij[0] = (rij[1]*rik[2]-rij[2]*rik[1]);
-                crosskij[1] = (rij[2]*rik[0]-rij[0]*rik[2]);
-                crosskij[2] = (rij[0]*rik[1]-rij[1]*rik[0]);
-                crosskijmag = sqrt(crosskij[0]*crosskij[0] +
-                                   crosskij[1]*crosskij[1] +
-                                   crosskij[2]*crosskij[2]);
-                crossijl[0] = (rij[1]*rjl[2]-rij[2]*rjl[1]);
-                crossijl[1] = (rij[2]*rjl[0]-rij[0]*rjl[2]);
-                crossijl[2] = (rij[0]*rjl[1]-rij[1]*rjl[0]);
-                crossijlmag = sqrt(crossijl[0]*crossijl[0] +
-                                   crossijl[1]*crossijl[1] +
-                                   crossijl[2]*crossijl[2]);
-                omkijl = -1.0*(((crosskij[0]*crossijl[0]) +
-                                (crosskij[1]*crossijl[1]) +
-                                (crosskij[2]*crossijl[2])) /
-                               (crosskijmag*crossijlmag));
-                Etmp += ((1.0-square(omkijl))*wik*wjl) *
-                  (1.0-tspjik)*(1.0-tspijl);
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  bij = (.5*(pij+pji))+piRC+(Tij*Etmp);
-  Stb = Sp2(bij,bLJmin[itype][jtype],bLJmax[itype][jtype],dStb);
-  VA = VA*dStb;
-
-  if (dStb != 0.0) {
-    tmp = tmppij;
-    dN2[0] = dN2PIJ[0];
-    dN2[1] = dN2PIJ[1];
-    tmp3 = tmp3pij;
-
-    const double invrijm = 1.0/rijmag;
-    const double invrijm2 = invrijm*invrijm;
-
-    // pij forces
-
-    REBO_neighs_i = REBO_firstneigh[i];
-    for (k = 0; k < REBO_numneigh[i]; k++) {
-      atomk = REBO_neighs_i[k];
-      ktype = map[type[atomk]];
-      if (atomk != atomj) {
-        lamdajik = 0.0;
-        rik[0] = x[atomi][0]-x[atomk][0];
-        rik[1] = x[atomi][1]-x[atomk][1];
-        rik[2] = x[atomi][2]-x[atomk][2];
-        rikmag = sqrt(rik[0]*rik[0] + rik[1]*rik[1] + rik[2]*rik[2]);
-        lamdajik = 4.0*kronecker(itype,1) *
-          ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
-        wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+          Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34));
+          Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34));
+          Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34));
+          fj[0] += Ftmp[0];
+          fj[1] += Ftmp[1];
+          fj[2] += Ftmp[2];
+          fl[0] = -Ftmp[0];
+          fl[1] = -Ftmp[1];
+          fl[2] = -Ftmp[2];
 
-        const double invrikm = 1.0/rikmag;
-        const double invrijkm = invrijm*invrikm;
-        const double invrikm2 = invrikm*invrikm;
+          Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril;
+          Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril;
+          Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril;
+          fi[0] += Ftmp[0];
+          fi[1] += Ftmp[1];
+          fi[2] += Ftmp[2];
+          fl[0] -= Ftmp[0];
+          fl[1] -= Ftmp[1];
+          fl[2] -= Ftmp[2];
 
-        cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2]))
-          * invrijkm;
-        cosjik = MIN(cosjik,1.0);
-        cosjik = MAX(cosjik,-1.0);
+          // coordination forces
 
-        dcosjikdri[0] = ((rij[0]+rik[0])*invrijkm) -
-          (cosjik*((rij[0]*invrijm2)+(rik[0]*invrikm2)));
-        dcosjikdri[1] = ((rij[1]+rik[1])*invrijkm) -
-          (cosjik*((rij[1]*invrijm2)+(rik[1]*invrikm2)));
-        dcosjikdri[2] = ((rij[2]+rik[2])*invrijkm) -
-          (cosjik*((rij[2]*invrijm2)+(rik[2]*invrikm2)));
-        dcosjikdrk[0] = (-rij[0]*invrijkm) + (cosjik*(rik[0]*invrikm2));
-        dcosjikdrk[1] = (-rij[1]*invrijkm) + (cosjik*(rik[1]*invrikm2));
-        dcosjikdrk[2] = (-rij[2]*invrijkm) + (cosjik*(rik[2]*invrikm2));
-        dcosjikdrj[0] = (-rik[0]*invrijkm) + (cosjik*(rij[0]*invrijm2));
-        dcosjikdrj[1] = (-rik[1]*invrijkm) + (cosjik*(rij[1]*invrijm2));
-        dcosjikdrj[2] = (-rik[2]*invrijkm) + (cosjik*(rij[2]*invrijm2));
+          fpair = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21;
+          fi[0] -= del21[0]*fpair;
+          fi[1] -= del21[1]*fpair;
+          fi[2] -= del21[2]*fpair;
+          fk[0] += del21[0]*fpair;
+          fk[1] += del21[1]*fpair;
+          fk[2] += del21[2]*fpair;
 
-        g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
+          fpair = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23;
+          fi[0] -= del23[0]*fpair;
+          fi[1] -= del23[1]*fpair;
+          fi[2] -= del23[2]*fpair;
+          fj[0] += del23[0]*fpair;
+          fj[1] += del23[1]*fpair;
+          fj[2] += del23[2]*fpair;
 
-        tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
-        fj[0] = -tmp2*dcosjikdrj[0];
-        fj[1] = -tmp2*dcosjikdrj[1];
-        fj[2] = -tmp2*dcosjikdrj[2];
-        fi[0] = -tmp2*dcosjikdri[0];
-        fi[1] = -tmp2*dcosjikdri[1];
-        fi[2] = -tmp2*dcosjikdri[2];
-        fk[0] = -tmp2*dcosjikdrk[0];
-        fk[1] = -tmp2*dcosjikdrk[1];
-        fk[2] = -tmp2*dcosjikdrk[2];
+          fpair = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34;
+          fj[0] -= del34[0]*fpair;
+          fj[1] -= del34[1]*fpair;
+          fj[2] -= del34[2]*fpair;
+          fl[0] += del34[0]*fpair;
+          fl[1] += del34[1]*fpair;
+          fl[2] += del34[2]*fpair;
 
-        tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
-        fj[0] -= tmp2*(-rij[0]*invrijm);
-        fj[1] -= tmp2*(-rij[1]*invrijm);
-        fj[2] -= tmp2*(-rij[2]*invrijm);
-        fi[0] -= tmp2*((-rik[0]/rikmag)+(rij[0]*invrijm));
-        fi[1] -= tmp2*((-rik[1]/rikmag)+(rij[1]*invrijm));
-        fi[2] -= tmp2*((-rik[2]/rikmag)+(rij[2]*invrijm));
-        fk[0] -= tmp2*(rik[0]/rikmag);
-        fk[1] -= tmp2*(rik[1]/rikmag);
-        fk[2] -= tmp2*(rik[2]/rikmag);
+          // additional cut off function forces
 
-        // coordination forces
+          fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl);
+          fpair = fcpc*dcidij/rij;
+          fi[0] += fpair*del23[0];
+          fi[1] += fpair*del23[1];
+          fi[2] += fpair*del23[2];
+          fj[0] -= fpair*del23[0];
+          fj[1] -= fpair*del23[1];
+          fj[2] -= fpair*del23[2];
 
-        // dwik forces
+          fpair = fcpc*dcidik/rik;
+          fi[0] += fpair*del21[0];
+          fi[1] += fpair*del21[1];
+          fi[2] += fpair*del21[2];
+          fk[0] -= fpair*del21[0];
+          fk[1] -= fpair*del21[1];
+          fk[2] -= fpair*del21[2];
 
-        tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag;
-        fi[0] -= tmp2*rik[0];
-        fi[1] -= tmp2*rik[1];
-        fi[2] -= tmp2*rik[2];
-        fk[0] += tmp2*rik[0];
-        fk[1] += tmp2*rik[1];
-        fk[2] += tmp2*rik[2];
+          fpair = fcpc*dcidjk/rjk;
+          fj[0] += fpair*deljk[0];
+          fj[1] += fpair*deljk[1];
+          fj[2] += fpair*deljk[2];
+          fk[0] -= fpair*deljk[0];
+          fk[1] -= fpair*deljk[1];
+          fk[2] -= fpair*deljk[2];
 
-        // PIJ forces
+          fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl;
+          fpair = fcpc*dcjdji/rij;
+          fi[0] += fpair*del23[0];
+          fi[1] += fpair*del23[1];
+          fi[2] += fpair*del23[2];
+          fj[0] -= fpair*del23[0];
+          fj[1] -= fpair*del23[1];
+          fj[2] -= fpair*del23[2];
 
-        tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag;
-        fi[0] -= tmp2*rik[0];
-        fi[1] -= tmp2*rik[1];
-        fi[2] -= tmp2*rik[2];
-        fk[0] += tmp2*rik[0];
-        fk[1] += tmp2*rik[1];
-        fk[2] += tmp2*rik[2];
+          fpair = fcpc*dcjdjl/rjl;
+          fj[0] += fpair*del34[0];
+          fj[1] += fpair*del34[1];
+          fj[2] += fpair*del34[2];
+          fl[0] -= fpair*del34[0];
+          fl[1] -= fpair*del34[1];
+          fl[2] -= fpair*del34[2];
 
-        // dgdN forces
+          fpair = fcpc*dcjdil/ril;
+          fi[0] += fpair*delil[0];
+          fi[1] += fpair*delil[1];
+          fi[2] += fpair*delil[2];
+          fl[0] -= fpair*delil[0];
+          fl[1] -= fpair*delil[1];
+          fl[2] -= fpair*delil[2];
 
-        tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag;
-        fi[0] -= tmp2*rik[0];
-        fi[1] -= tmp2*rik[1];
-        fi[2] -= tmp2*rik[2];
-        fk[0] += tmp2*rik[0];
-        fk[1] += tmp2*rik[1];
-        fk[2] += tmp2*rik[2];
+          // sum per-atom forces into atom force array
 
-        f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
-        f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
-        f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
+          f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2];
+          f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2];
+          f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2];
+          f[l][0] += fl[0]; f[l][1] += fl[1]; f[l][2] += fl[2];
 
-        if (vflag_atom) {
-          rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
-          rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
-          v_tally3_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr);
+          if (evflag) {
+            delkl[0] = delil[0] - del21[0];
+            delkl[1] = delil[1] - del21[1];
+            delkl[2] = delil[2] - del21[2];
+            ev_tally4_thr(this,i,j,k,l,evdwl,fi,fj,fk,delil,del34,delkl,thr);
+          }
         }
       }
     }
+  }
+}
 
-    tmp = tmppji;
-    tmp3 = tmp3pji;
-    dN2[0] = dN2PJI[0];
-    dN2[1] = dN2PJI[1];
-    REBO_neighs  =  REBO_firstneigh[j];
-    for (l = 0; l < REBO_numneigh[j]; l++) {
-      atoml = REBO_neighs[l];
-      if (atoml !=atomi) {
-        ltype = map[type[atoml]];
-        rjl[0] = x[atomj][0]-x[atoml][0];
-        rjl[1] = x[atomj][1]-x[atoml][1];
-        rjl[2] = x[atomj][2]-x[atoml][2];
-        rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-        lamdaijl = 4.0*kronecker(jtype,1) *
-          ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
-        wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+/* ----------------------------------------------------------------------
+   Bij function
+------------------------------------------------------------------------- */
 
-        const double invrjlm = 1.0/rjlmag;
-        const double invrijlm = invrijm*invrjlm;
-        const double invrjlm2 = invrjlm*invrjlm;
+double PairAIREBOOMP::bondorder_thr(int i, int j, double rij[3], double rijmag,
+                                    double VA, int vflag_atom, ThrData * const thr)
+{
+  int atomi,atomj,k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
+  int itype,jtype,ktype,ltype,ntype;
+  double rik[3],rjl[3],rkn[3],rji[3],rki[3],rlj[3],rknmag,dNki,dwjl,bij;
+  double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
+  double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
+  double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ,Nki,Nlj,dS;
+  double lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
+  double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
+  double dN2[2],dN3[3];
+  double dcosjikdrj[3],dcosijldrj[3],dcosijldrl[3];
+  double Tij;
+  double r32[3],r32mag,cos321,r43[3],r13[3];
+  double dNlj;
+  double om1234,rln[3];
+  double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
+  double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
+  double cross321[3],cross234[3],prefactor,SpN;
+  double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
+  double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
+  double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
+  double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
+  double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
+  double F23[3],F12[3],F34[3],F31[3],F24[3],fi[3],fj[3],fk[3],fl[3];
+  double f1[3],f2[3],f3[3],f4[4];
+  double dcut321,PijS,PjiS;
+  double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
+  int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
 
-        cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2]))) *
-          invrijlm;
-        cosijl = MIN(cosijl,1.0);
-        cosijl = MAX(cosijl,-1.0);
+  const double * const * const x = atom->x;
+  double * const * const f = thr->get_f();
+  int *type = atom->type;
 
-        dcosijldri[0] = (-rjl[0]*invrijlm) - (cosijl*rij[0]*invrijm2);
-        dcosijldri[1] = (-rjl[1]*invrijlm) - (cosijl*rij[1]*invrijm2);
-        dcosijldri[2] = (-rjl[2]*invrijlm) - (cosijl*rij[2]*invrijm2);
-        dcosijldrj[0] = ((-rij[0]+rjl[0])*invrijlm) +
-          (cosijl*((rij[0]*invrijm2)-(rjl[0]*invrjlm2)));
-        dcosijldrj[1] = ((-rij[1]+rjl[1])*invrijlm) +
-          (cosijl*((rij[1]*invrijm2)-(rjl[1]*invrjlm2)));
-        dcosijldrj[2] = ((-rij[2]+rjl[2])*invrijlm) +
-          (cosijl*((rij[2]*invrijm2)-(rjl[2]*invrjlm2)));
-        dcosijldrl[0] = (rij[0]*invrijlm) + (cosijl*rjl[0]*invrjlm2);
-        dcosijldrl[1] = (rij[1]*invrijlm) + (cosijl*rjl[1]*invrjlm2);
-        dcosijldrl[2] = (rij[2]*invrijlm) + (cosijl*rjl[2]*invrjlm2);
+  atomi = i;
+  atomj = j;
+  itype = map[type[i]];
+  jtype = map[type[j]];
+  wij = Sp(rijmag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+  NijC = nC[i]-(wij*kronecker(jtype,0));
+  NijH = nH[i]-(wij*kronecker(jtype,1));
+  NjiC = nC[j]-(wij*kronecker(itype,0));
+  NjiH = nH[j]-(wij*kronecker(itype,1));
+  bij = 0.0;
+  tmp = 0.0;
+  tmp2 = 0.0;
+  tmp3 = 0.0;
+  dgdc = 0.0;
+  dgdN = 0.0;
+  NconjtmpI = 0.0;
+  NconjtmpJ = 0.0;
+  Etmp = 0.0;
 
-        // evaluate splines g and derivatives dg
+  REBO_neighs = REBO_firstneigh[i];
+  for (k = 0; k < REBO_numneigh[i]; k++) {
+    atomk = REBO_neighs[k];
+    if (atomk != atomj) {
+      ktype = map[type[atomk]];
+      rik[0] = x[atomi][0]-x[atomk][0];
+      rik[1] = x[atomi][1]-x[atomk][1];
+      rik[2] = x[atomi][2]-x[atomk][2];
+      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+      lamdajik = 4.0*kronecker(itype,1) *
+        ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
+      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
+      Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+        (wik*kronecker(itype,1));
+      cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
+        (rijmag*rikmag);
+      cosjik = MIN(cosjik,1.0);
+      cosjik = MAX(cosjik,-1.0);
 
-        g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
-        tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
-        fi[0] = -tmp2*dcosijldri[0];
-        fi[1] = -tmp2*dcosijldri[1];
-        fi[2] = -tmp2*dcosijldri[2];
-        fj[0] = -tmp2*dcosijldrj[0];
-        fj[1] = -tmp2*dcosijldrj[1];
-        fj[2] = -tmp2*dcosijldrj[2];
-        fl[0] = -tmp2*dcosijldrl[0];
-        fl[1] = -tmp2*dcosijldrl[1];
-        fl[2] = -tmp2*dcosijldrl[2];
+      // evaluate splines g and derivatives dg
 
-        tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
-        fi[0] -= tmp2*(rij[0]*invrijm);
-        fi[1] -= tmp2*(rij[1]*invrijm);
-        fi[2] -= tmp2*(rij[2]*invrijm);
-        fj[0] -= tmp2*((-rjl[0]*invrjlm)-(rij[0]*invrijm));
-        fj[1] -= tmp2*((-rjl[1]*invrjlm)-(rij[1]*invrijm));
-        fj[2] -= tmp2*((-rjl[2]*invrjlm)-(rij[2]*invrijm));
-        fl[0] -= tmp2*(rjl[0]*invrjlm);
-        fl[1] -= tmp2*(rjl[1]*invrjlm);
-        fl[2] -= tmp2*(rjl[2]*invrjlm);
+      g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
+      Etmp = Etmp+(wik*g*exp(lamdajik));
+      tmp3 = tmp3+(wik*dgdN*exp(lamdajik));
+      NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
+    }
+  }
 
-         // coordination forces
-        // dwik forces
+  PijS = 0.0;
+  dN2[0] = 0.0;
+  dN2[1] = 0.0;
+  PijS = PijSpline(NijC,NijH,itype,jtype,dN2);
+  pij = 1.0/sqrt(1.0+Etmp+PijS);
+  tmp = -0.5*pij*pij*pij;
 
-        tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))*invrjlm;
-        fj[0] -= tmp2*rjl[0];
-        fj[1] -= tmp2*rjl[1];
-        fj[2] -= tmp2*rjl[2];
-        fl[0] += tmp2*rjl[0];
-        fl[1] += tmp2*rjl[1];
-        fl[2] += tmp2*rjl[2];
+  const double invrijm = 1.0/rijmag;
+  const double invrijm2 = invrijm*invrijm;
 
-        // PIJ forces
+  // pij forces
 
-        tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)*invrjlm;
-        fj[0] -= tmp2*rjl[0];
-        fj[1] -= tmp2*rjl[1];
-        fj[2] -= tmp2*rjl[2];
-        fl[0] += tmp2*rjl[0];
-        fl[1] += tmp2*rjl[1];
-        fl[2] += tmp2*rjl[2];
+  REBO_neighs = REBO_firstneigh[i];
+  for (k = 0; k < REBO_numneigh[i]; k++) {
+    atomk = REBO_neighs[k];
+    if (atomk != atomj) {
+      ktype = map[type[atomk]];
+      rik[0] = x[atomi][0]-x[atomk][0];
+      rik[1] = x[atomi][1]-x[atomk][1];
+      rik[2] = x[atomi][2]-x[atomk][2];
+      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+      lamdajik = 4.0*kronecker(itype,1) *
+        ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
+      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
 
-        // dgdN forces
+      const double invrikm = 1.0/rikmag;
+      const double invrijkm = invrijm*invrikm;
+      const double invrikm2 = invrikm*invrikm;
 
-        tmp2=VA*.5*(tmp*tmp3*dwjl)*invrjlm;
-        fj[0] -= tmp2*rjl[0];
-        fj[1] -= tmp2*rjl[1];
-        fj[2] -= tmp2*rjl[2];
-        fl[0] += tmp2*rjl[0];
-        fl[1] += tmp2*rjl[1];
-        fl[2] += tmp2*rjl[2];
+      cosjik = (rij[0]*rik[0] + rij[1]*rik[1] + rij[2]*rik[2]) * invrijkm;
+      cosjik = MIN(cosjik,1.0);
+      cosjik = MAX(cosjik,-1.0);
 
-        f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
-        f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
-        f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
+      dcosjikdri[0] = ((rij[0]+rik[0])*invrijkm) -
+        (cosjik*((rij[0]*invrijm2)+(rik[0]*invrikm2)));
+      dcosjikdri[1] = ((rij[1]+rik[1])*invrijkm) -
+        (cosjik*((rij[1]*invrijm2)+(rik[1]*invrikm2)));
+      dcosjikdri[2] = ((rij[2]+rik[2])*invrijkm) -
+        (cosjik*((rij[2]*invrijm2)+(rik[2]*invrikm2)));
+      dcosjikdrk[0] = (-rij[0]*invrijkm) + (cosjik*(rik[0]*invrikm2));
+      dcosjikdrk[1] = (-rij[1]*invrijkm) + (cosjik*(rik[1]*invrikm2));
+      dcosjikdrk[2] = (-rij[2]*invrijkm) + (cosjik*(rik[2]*invrikm2));
+      dcosjikdrj[0] = (-rik[0]*invrijkm) + (cosjik*(rij[0]*invrijm2));
+      dcosjikdrj[1] = (-rik[1]*invrijkm) + (cosjik*(rij[1]*invrijm2));
+      dcosjikdrj[2] = (-rik[2]*invrijkm) + (cosjik*(rij[2]*invrijm2));
 
-        if (vflag_atom) {
-          rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
-          v_tally3_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr);
-        }
-      }
-    }
+      g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
+      tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
+      fj[0] = -tmp2*dcosjikdrj[0];
+      fj[1] = -tmp2*dcosjikdrj[1];
+      fj[2] = -tmp2*dcosjikdrj[2];
+      fi[0] = -tmp2*dcosjikdri[0];
+      fi[1] = -tmp2*dcosjikdri[1];
+      fi[2] = -tmp2*dcosjikdri[2];
+      fk[0] = -tmp2*dcosjikdrk[0];
+      fk[1] = -tmp2*dcosjikdrk[1];
+      fk[2] = -tmp2*dcosjikdrk[2];
 
-    // piRC forces
+      tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
+      fj[0] -= tmp2*(-rij[0]*invrijm);
+      fj[1] -= tmp2*(-rij[1]*invrijm);
+      fj[2] -= tmp2*(-rij[2]*invrijm);
+      fi[0] -= tmp2*((-rik[0]*invrikm)+(rij[0]*invrijm));
+      fi[1] -= tmp2*((-rik[1]*invrikm)+(rij[1]*invrijm));
+      fi[2] -= tmp2*((-rik[2]*invrikm)+(rij[2]*invrijm));
+      fk[0] -= tmp2*(rik[0]*invrikm);
+      fk[1] -= tmp2*(rik[1]*invrikm);
+      fk[2] -= tmp2*(rik[2]*invrikm);
 
-    dN3[0] = dN3piRC[0];
-    dN3[1] = dN3piRC[1];
-    dN3[2] = dN3piRC[2];
+      // coordination forces
 
-    REBO_neighs_i = REBO_firstneigh[i];
-    for (k = 0; k < REBO_numneigh[i]; k++) {
-      atomk = REBO_neighs_i[k];
-      if (atomk != atomj) {
-        ktype = map[type[atomk]];
-        rik[0] = x[atomi][0]-x[atomk][0];
-        rik[1] = x[atomi][1]-x[atomk][1];
-        rik[2] = x[atomi][2]-x[atomk][2];
-        rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-        wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
-        Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
-          (wik*kronecker(itype,1));
-        SpN = Sp(Nki,Nmin,Nmax,dNki);
+      // dwik forces
 
-        tmp2 = VA*dN3[0]*dwik/rikmag;
-        f[atomi][0] -= tmp2*rik[0];
-        f[atomi][1] -= tmp2*rik[1];
-        f[atomi][2] -= tmp2*rik[2];
-        f[atomk][0] += tmp2*rik[0];
-        f[atomk][1] += tmp2*rik[1];
-        f[atomk][2] += tmp2*rik[2];
+      tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))*invrikm;
+      fi[0] -= tmp2*rik[0];
+      fi[1] -= tmp2*rik[1];
+      fi[2] -= tmp2*rik[2];
+      fk[0] += tmp2*rik[0];
+      fk[1] += tmp2*rik[1];
+      fk[2] += tmp2*rik[2];
 
-        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+      // PIJ forces
 
-        tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
-        f[atomi][0] -= tmp2*rik[0];
-        f[atomi][1] -= tmp2*rik[1];
-        f[atomi][2] -= tmp2*rik[2];
-        f[atomk][0] += tmp2*rik[0];
-        f[atomk][1] += tmp2*rik[1];
-        f[atomk][2] += tmp2*rik[2];
+      tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)*invrikm;
+      fi[0] -= tmp2*rik[0];
+      fi[1] -= tmp2*rik[1];
+      fi[2] -= tmp2*rik[2];
+      fk[0] += tmp2*rik[0];
+      fk[1] += tmp2*rik[1];
+      fk[2] += tmp2*rik[2];
 
-        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+      // dgdN forces
 
-        if (fabs(dNki) > TOL) {
-          REBO_neighs_k = REBO_firstneigh[atomk];
-          for (n = 0; n < REBO_numneigh[atomk]; n++) {
-            atomn = REBO_neighs_k[n];
-            if (atomn != atomi) {
-              ntype = map[type[atomn]];
-              rkn[0] = x[atomk][0]-x[atomn][0];
-              rkn[1] = x[atomk][1]-x[atomn][1];
-              rkn[2] = x[atomk][2]-x[atomn][2];
-              rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
-              Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
+      tmp2 = VA*.5*(tmp*tmp3*dwik)*invrikm;
+      fi[0] -= tmp2*rik[0];
+      fi[1] -= tmp2*rik[1];
+      fi[2] -= tmp2*rik[2];
+      fk[0] += tmp2*rik[0];
+      fk[1] += tmp2*rik[1];
+      fk[2] += tmp2*rik[2];
 
-              tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
-              f[atomk][0] -= tmp2*rkn[0];
-              f[atomk][1] -= tmp2*rkn[1];
-              f[atomk][2] -= tmp2*rkn[2];
-              f[atomn][0] += tmp2*rkn[0];
-              f[atomn][1] += tmp2*rkn[1];
-              f[atomn][2] += tmp2*rkn[2];
+      f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+      f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+      f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
 
-              if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
-            }
-          }
-        }
+      if (vflag_atom) {
+        rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
+        rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
+        v_tally3_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr);
       }
     }
+  }
 
-    // piRC forces to J side
+  tmp = 0.0;
+  tmp2 = 0.0;
+  tmp3 = 0.0;
+  Etmp = 0.0;
 
-    REBO_neighs = REBO_firstneigh[j];
-    for (l = 0; l < REBO_numneigh[j]; l++) {
-      atoml = REBO_neighs[l];
-      if (atoml != atomi) {
-        ltype = map[type[atoml]];
-        rjl[0] = x[atomj][0]-x[atoml][0];
-        rjl[1] = x[atomj][1]-x[atoml][1];
-        rjl[2] = x[atomj][2]-x[atoml][2];
-        rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-        wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
-        Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
-          (wjl*kronecker(jtype,1));
-        SpN = Sp(Nlj,Nmin,Nmax,dNlj);
+  REBO_neighs = REBO_firstneigh[j];
+  for (l = 0; l < REBO_numneigh[j]; l++) {
+    atoml = REBO_neighs[l];
+    if (atoml != atomi) {
+      ltype = map[type[atoml]];
+      rjl[0] = x[atomj][0]-x[atoml][0];
+      rjl[1] = x[atomj][1]-x[atoml][1];
+      rjl[2] = x[atomj][2]-x[atoml][2];
+      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+      lamdaijl = 4.0*kronecker(jtype,1) *
+        ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
+      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
+      Nlj = nC[atoml]-(wjl*kronecker(jtype,0)) +
+        nH[atoml]-(wjl*kronecker(jtype,1));
+      cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
+        (rijmag*rjlmag);
+      cosijl = MIN(cosijl,1.0);
+      cosijl = MAX(cosijl,-1.0);
 
-        tmp2 = VA*dN3[1]*dwjl/rjlmag;
-        f[atomj][0] -= tmp2*rjl[0];
-        f[atomj][1] -= tmp2*rjl[1];
-        f[atomj][2] -= tmp2*rjl[2];
-        f[atoml][0] += tmp2*rjl[0];
-        f[atoml][1] += tmp2*rjl[1];
-        f[atoml][2] += tmp2*rjl[2];
+      // evaluate splines g and derivatives dg
 
-        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+      g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
+      Etmp = Etmp+(wjl*g*exp(lamdaijl));
+      tmp3 = tmp3+(wjl*dgdN*exp(lamdaijl));
+      NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
+    }
+  }
 
-        tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
-        f[atomj][0] -= tmp2*rjl[0];
-        f[atomj][1] -= tmp2*rjl[1];
-        f[atomj][2] -= tmp2*rjl[2];
-        f[atoml][0] += tmp2*rjl[0];
-        f[atoml][1] += tmp2*rjl[1];
-        f[atoml][2] += tmp2*rjl[2];
+  PjiS = 0.0;
+  dN2[0] = 0.0;
+  dN2[1] = 0.0;
+  PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2);
+  pji = 1.0/sqrt(1.0+Etmp+PjiS);
+  tmp = -0.5*pji*pji*pji;
 
-        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+  REBO_neighs = REBO_firstneigh[j];
+  for (l = 0; l < REBO_numneigh[j]; l++) {
+    atoml = REBO_neighs[l];
+    if (atoml != atomi) {
+      ltype = map[type[atoml]];
+      rjl[0] = x[atomj][0]-x[atoml][0];
+      rjl[1] = x[atomj][1]-x[atoml][1];
+      rjl[2] = x[atomj][2]-x[atoml][2];
+      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+      lamdaijl = 4.0*kronecker(jtype,1) *
+        ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
+      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
 
-        if (fabs(dNlj) > TOL) {
-          REBO_neighs_l = REBO_firstneigh[atoml];
-          for (n = 0; n < REBO_numneigh[atoml]; n++) {
-            atomn = REBO_neighs_l[n];
-            if (atomn != atomj) {
-              ntype = map[type[atomn]];
-              rln[0] = x[atoml][0]-x[atomn][0];
-              rln[1] = x[atoml][1]-x[atomn][1];
-              rln[2] = x[atoml][2]-x[atomn][2];
-              rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
-              Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
+      const double invrjlm = 1.0/rjlmag;
+      const double invrijlm = invrijm*invrjlm;
+      const double invrjlm2 = invrjlm*invrjlm;
 
-              tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
-              f[atoml][0] -= tmp2*rln[0];
-              f[atoml][1] -= tmp2*rln[1];
-              f[atoml][2] -= tmp2*rln[2];
-              f[atomn][0] += tmp2*rln[0];
-              f[atomn][1] += tmp2*rln[1];
-              f[atomn][2] += tmp2*rln[2];
+      cosijl = (-1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])))
+        * invrijlm;
 
-              if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
-            }
-          }
-        }
-      }
-    }
+      cosijl = MIN(cosijl,1.0);
+      cosijl = MAX(cosijl,-1.0);
 
-    if (fabs(Tij) > TOL) {
-      dN3[0] = dN3Tij[0];
-      dN3[1] = dN3Tij[1];
-      dN3[2] = dN3Tij[2];
-      atom2 = atomi;
-      atom3 = atomj;
-      r32[0] = x[atom3][0]-x[atom2][0];
-      r32[1] = x[atom3][1]-x[atom2][1];
-      r32[2] = x[atom3][2]-x[atom2][2];
-      r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
-      r23[0] = -r32[0];
-      r23[1] = -r32[1];
-      r23[2] = -r32[2];
-      r23mag = r32mag;
+      dcosijldri[0] = (-rjl[0]*invrijlm) - (cosijl*rij[0]*invrijm2);
+      dcosijldri[1] = (-rjl[1]*invrijlm) - (cosijl*rij[1]*invrijm2);
+      dcosijldri[2] = (-rjl[2]*invrijlm) - (cosijl*rij[2]*invrijm2);
+      dcosijldrj[0] = ((-rij[0]+rjl[0])*invrijlm) +
+        (cosijl*((rij[0]*invrijm2)-(rjl[0]*invrjlm2)));
+      dcosijldrj[1] = ((-rij[1]+rjl[1])*invrijlm) +
+        (cosijl*((rij[1]*invrijm2)-(rjl[1]*invrjlm2)));
+      dcosijldrj[2] = ((-rij[2]+rjl[2])*invrijlm) +
+        (cosijl*((rij[2]*invrijm2)-(rjl[2]*invrjlm2)));
+      dcosijldrl[0] = (rij[0]*invrijlm)+(cosijl*rjl[0]*invrjlm2);
+      dcosijldrl[1] = (rij[1]*invrijlm)+(cosijl*rjl[1]*invrjlm2);
+      dcosijldrl[2] = (rij[2]*invrijlm)+(cosijl*rjl[2]*invrjlm2);
 
-      REBO_neighs_i = REBO_firstneigh[i];
-      for (k = 0; k < REBO_numneigh[i]; k++) {
-        atomk = REBO_neighs_i[k];
-        atom1 = atomk;
-        ktype = map[type[atomk]];
-        if (atomk != atomj) {
-          r21[0] = x[atom2][0]-x[atom1][0];
-          r21[1] = x[atom2][1]-x[atom1][1];
-          r21[2] = x[atom2][2]-x[atom1][2];
-          r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
-          cos321 = ((r21[0]*rij[0])+(r21[1]*rij[1])+(r21[2]*rij[2])) /
-            (r21mag*rijmag);
-          cos321 = MIN(cos321,1.0);
-          cos321 = MAX(cos321,-1.0);
-          sin321 = sqrt(1.0 - cos321*cos321);
+      // evaluate splines g and derivatives dg
 
-          if ((sin321 > TOL) && (r21mag > TOL)) { // XXX was sin321 != 0.0
-            sink2i = 1.0/(sin321*sin321);
-            rik2i = 1.0/(r21mag*r21mag);
-            rr = (rijmag*rijmag)-(r21mag*r21mag);
-            rjk[0] = r21[0]-rij[0];
-            rjk[1] = r21[1]-rij[1];
-            rjk[2] = r21[2]-rij[2];
-            rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
-            rijrik = 2.0*rijmag*r21mag;
-            rik2 = r21mag*r21mag;
-            dctik = (-rr+rjk2)/(rijrik*rik2);
-            dctij = (rr+rjk2)/(rijrik*rijmag*rijmag);
-            dctjk = -2.0/rijrik;
-            w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
-            rikmag = r21mag;
-            rij2 = r32mag*r32mag;
-            rik2 = r21mag*r21mag;
-            costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
-            tspjik = Sp2(costmp,thmin,thmax,dtsjik);
-            dtsjik = -dtsjik;
+      g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
+      tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
+      fi[0] = -tmp2*dcosijldri[0];
+      fi[1] = -tmp2*dcosijldri[1];
+      fi[2] = -tmp2*dcosijldri[2];
+      fj[0] = -tmp2*dcosijldrj[0];
+      fj[1] = -tmp2*dcosijldrj[1];
+      fj[2] = -tmp2*dcosijldrj[2];
+      fl[0] = -tmp2*dcosijldrl[0];
+      fl[1] = -tmp2*dcosijldrl[1];
+      fl[2] = -tmp2*dcosijldrl[2];
 
-            REBO_neighs_j = REBO_firstneigh[j];
-            for (l = 0; l < REBO_numneigh[j]; l++) {
-              atoml = REBO_neighs_j[l];
-              atom4 = atoml;
-              ltype = map[type[atoml]];
-              if (!(atoml == atomi || atoml == atomk)) {
-                r34[0] = x[atom3][0]-x[atom4][0];
-                r34[1] = x[atom3][1]-x[atom4][1];
-                r34[2] = x[atom3][2]-x[atom4][2];
-                r34mag = sqrt(r34[0]*r34[0] + r34[1]*r34[1] + r34[2]*r34[2]);
-                cos234 = -1.0*((rij[0]*r34[0])+(rij[1]*r34[1]) +
-                               (rij[2]*r34[2]))/(rijmag*r34mag);
-                cos234 = MIN(cos234,1.0);
-                cos234 = MAX(cos234,-1.0);
-                sin234 = sqrt(1.0 - cos234*cos234);
+      tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
+      fi[0] -= tmp2*(rij[0]*invrijm);
+      fi[1] -= tmp2*(rij[1]*invrijm);
+      fi[2] -= tmp2*(rij[2]*invrijm);
+      fj[0] -= tmp2*((-rjl[0]*invrjlm)-(rij[0]*invrijm));
+      fj[1] -= tmp2*((-rjl[1]*invrjlm)-(rij[1]*invrijm));
+      fj[2] -= tmp2*((-rjl[2]*invrjlm)-(rij[2]*invrijm));
+      fl[0] -= tmp2*(rjl[0]*invrjlm);
+      fl[1] -= tmp2*(rjl[1]*invrjlm);
+      fl[2] -= tmp2*(rjl[2]*invrjlm);
 
-                if ((sin234 > TOL) && (r34mag > TOL)) { // XXX was sin234 != 0.0
-                  sinl2i = 1.0/(sin234*sin234);
-                  rjl2i = 1.0/(r34mag*r34mag);
-                  w34 = Sp(r34mag,rcmin[jtype][ltype],
-                           rcmaxp[jtype][ltype],dw34);
-                  rr = (r23mag*r23mag)-(r34mag*r34mag);
-                  ril[0] = r23[0]+r34[0];
-                  ril[1] = r23[1]+r34[1];
-                  ril[2] = r23[2]+r34[2];
-                  ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
-                  rijrjl = 2.0*r23mag*r34mag;
-                  rjl2 = r34mag*r34mag;
-                  dctjl = (-rr+ril2)/(rijrjl*rjl2);
-                  dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
-                  dctil = -2.0/rijrjl;
-                  rjlmag = r34mag;
-                  rjl2 = r34mag*r34mag;
-                  costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
-                  tspijl = Sp2(costmp,thmin,thmax,dtsijl);
-                  dtsijl = -dtsijl; //need minus sign
-                  prefactor = VA*Tij;
+      // coordination forces
 
-                  cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
-                  cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
-                  cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
-                  cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
-                  cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
-                  cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
+      // dwik forces
 
-                  cwnum = (cross321[0]*cross234[0]) +
-                    (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
-                  cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
-                  om1234 = cwnum/cwnom;
-                  cw = om1234;
-                  Etmp += ((1.0-square(om1234))*w21*w34) *
-                    (1.0-tspjik)*(1.0-tspijl);
+      tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))*invrjlm;
+      fj[0] -= tmp2*rjl[0];
+      fj[1] -= tmp2*rjl[1];
+      fj[2] -= tmp2*rjl[2];
+      fl[0] += tmp2*rjl[0];
+      fl[1] += tmp2*rjl[1];
+      fl[2] += tmp2*rjl[2];
 
-                  dt1dik = (rik2i)-(dctik*sink2i*cos321);
-                  dt1djk = (-dctjk*sink2i*cos321);
-                  dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
-                  dt1dil = (-dctil*sinl2i*cos234);
-                  dt1dij = (2.0/(r23mag*r23mag)) -
-                    (dctij*sink2i*cos321)-(dctji*sinl2i*cos234);
+      // PIJ forces
 
-                  dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
-                  dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
-                  dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
+      tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)*invrjlm;
+      fj[0] -= tmp2*rjl[0];
+      fj[1] -= tmp2*rjl[1];
+      fj[2] -= tmp2*rjl[2];
+      fl[0] += tmp2*rjl[0];
+      fl[1] += tmp2*rjl[1];
+      fl[2] += tmp2*rjl[2];
 
-                  dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
-                  dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
-                  dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
+      // dgdN forces
 
-                  dt2dij[0] = (r21[2]*cross234[1]) -
-                    (r34[2]*cross321[1])-(r21[1]*cross234[2]) +
-                    (r34[1]*cross321[2]);
-                  dt2dij[1] = (r21[0]*cross234[2]) -
-                    (r34[0]*cross321[2])-(r21[2]*cross234[0]) +
-                    (r34[2]*cross321[0]);
-                  dt2dij[2] = (r21[1]*cross234[0]) -
-                    (r34[1]*cross321[0])-(r21[0]*cross234[1]) +
-                    (r34[0]*cross321[1]);
+      tmp2 = VA*.5*(tmp*tmp3*dwjl)*invrjlm;
+      fj[0] -= tmp2*rjl[0];
+      fj[1] -= tmp2*rjl[1];
+      fj[2] -= tmp2*rjl[2];
+      fl[0] += tmp2*rjl[0];
+      fl[1] += tmp2*rjl[1];
+      fl[2] += tmp2*rjl[2];
 
-                  aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
-                    (1.0-tspjik)*(1.0-tspijl);
-                  aaa1 = -prefactor*(1.0-square(om1234)) *
-                    (1.0-tspjik)*(1.0-tspijl);
-                  aaa2 = aaa1*w21*w34;
-                  at2 = aa*cwnum;
+      f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+      f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+      f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
 
-                  fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
-                    (aaa2*dtsijl*dctji*(1.0-tspjik));
-                  fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
-                  fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
-                  fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
-                  fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
+      if (vflag_atom) {
+        rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
+        v_tally3_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr);
+      }
+    }
+  }
 
-                  F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
-                  F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
-                  F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
+  // evaluate Nij conj
 
-                  F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
-                  F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
-                  F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
+  Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
+  piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3);
 
-                  F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
-                  F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
-                  F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
+  // piRC forces
 
-                  F31[0] = (fcjkpc*rjk[0]);
-                  F31[1] = (fcjkpc*rjk[1]);
-                  F31[2] = (fcjkpc*rjk[2]);
+  REBO_neighs_i = REBO_firstneigh[i];
+  for (k = 0; k < REBO_numneigh[i]; k++) {
+    atomk = REBO_neighs_i[k];
+    if (atomk !=atomj) {
+      ktype = map[type[atomk]];
+      rik[0] = x[atomi][0]-x[atomk][0];
+      rik[1] = x[atomi][1]-x[atomk][1];
+      rik[2] = x[atomi][2]-x[atomk][2];
+      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+      Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+        (wik*kronecker(itype,1));
+      SpN = Sp(Nki,Nmin,Nmax,dNki);
 
-                  F24[0] = (fcilpc*ril[0]);
-                  F24[1] = (fcilpc*ril[1]);
-                  F24[2] = (fcilpc*ril[2]);
+      tmp2 = VA*dN3[0]*dwik/rikmag;
+      f[atomi][0] -= tmp2*rik[0];
+      f[atomi][1] -= tmp2*rik[1];
+      f[atomi][2] -= tmp2*rik[2];
+      f[atomk][0] += tmp2*rik[0];
+      f[atomk][1] += tmp2*rik[1];
+      f[atomk][2] += tmp2*rik[2];
 
-                  f1[0] = -F12[0]-F31[0];
-                  f1[1] = -F12[1]-F31[1];
-                  f1[2] = -F12[2]-F31[2];
-                  f2[0] = F23[0]+F12[0]+F24[0];
-                  f2[1] = F23[1]+F12[1]+F24[1];
-                  f2[2] = F23[2]+F12[2]+F24[2];
-                  f3[0] = -F23[0]+F34[0]+F31[0];
-                  f3[1] = -F23[1]+F34[1]+F31[1];
-                  f3[2] = -F23[2]+F34[2]+F31[2];
-                  f4[0] = -F34[0]-F24[0];
-                  f4[1] = -F34[1]-F24[1];
-                  f4[2] = -F34[2]-F24[2];
+      if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-                  // coordination forces
+      tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
+      f[atomi][0] -= tmp2*rik[0];
+      f[atomi][1] -= tmp2*rik[1];
+      f[atomi][2] -= tmp2*rik[2];
+      f[atomk][0] += tmp2*rik[0];
+      f[atomk][1] += tmp2*rik[1];
+      f[atomk][2] += tmp2*rik[2];
 
-                  tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
-                    (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
-                  f2[0] -= tmp2*r21[0];
-                  f2[1] -= tmp2*r21[1];
-                  f2[2] -= tmp2*r21[2];
-                  f1[0] += tmp2*r21[0];
-                  f1[1] += tmp2*r21[1];
-                  f1[2] += tmp2*r21[2];
+      if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-                  tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
-                    (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
-                  f3[0] -= tmp2*r34[0];
-                  f3[1] -= tmp2*r34[1];
-                  f3[2] -= tmp2*r34[2];
-                  f4[0] += tmp2*r34[0];
-                  f4[1] += tmp2*r34[1];
-                  f4[2] += tmp2*r34[2];
+      if (fabs(dNki) > TOL) {
+        REBO_neighs_k = REBO_firstneigh[atomk];
+        for (n = 0; n < REBO_numneigh[atomk]; n++) {
+          atomn = REBO_neighs_k[n];
+          if (atomn != atomi) {
+            ntype = map[type[atomn]];
+            rkn[0] = x[atomk][0]-x[atomn][0];
+            rkn[1] = x[atomk][1]-x[atomn][1];
+            rkn[2] = x[atomk][2]-x[atomn][2];
+            rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
+            Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
 
-                  f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
-                  f[atom1][2] += f1[2];
-                  f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
-                  f[atom2][2] += f2[2];
-                  f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
-                  f[atom3][2] += f3[2];
-                  f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
-                  f[atom4][2] += f4[2];
+            tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
+            f[atomk][0] -= tmp2*rkn[0];
+            f[atomk][1] -= tmp2*rkn[1];
+            f[atomk][2] -= tmp2*rkn[2];
+            f[atomn][0] += tmp2*rkn[0];
+            f[atomn][1] += tmp2*rkn[1];
+            f[atomn][2] += tmp2*rkn[2];
 
-                  if (vflag_atom) {
-                    r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
-                    r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
-                    v_tally4_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr);
-                  }
-                }
-              }
-            }
+            if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
           }
         }
       }
+    }
+  }
 
-      REBO_neighs = REBO_firstneigh[i];
-      for (k = 0; k < REBO_numneigh[i]; k++) {
-        atomk = REBO_neighs[k];
-        if (atomk != atomj) {
-          ktype = map[type[atomk]];
-          rik[0] = x[atomi][0]-x[atomk][0];
-          rik[1] = x[atomi][1]-x[atomk][1];
-          rik[2] = x[atomi][2]-x[atomk][2];
-          rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
-          wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
-          Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
-            (wik*kronecker(itype,1));
-          SpN = Sp(Nki,Nmin,Nmax,dNki);
+  // piRC forces
 
-          tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
-          f[atomi][0] -= tmp2*rik[0];
-          f[atomi][1] -= tmp2*rik[1];
-          f[atomi][2] -= tmp2*rik[2];
-          f[atomk][0] += tmp2*rik[0];
-          f[atomk][1] += tmp2*rik[1];
-          f[atomk][2] += tmp2*rik[2];
+  REBO_neighs = REBO_firstneigh[atomj];
+  for (l = 0; l < REBO_numneigh[atomj]; l++) {
+    atoml = REBO_neighs[l];
+    if (atoml !=atomi) {
+      ltype = map[type[atoml]];
+      rjl[0] = x[atomj][0]-x[atoml][0];
+      rjl[1] = x[atomj][1]-x[atoml][1];
+      rjl[2] = x[atomj][2]-x[atoml][2];
+      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+      Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+        (wjl*kronecker(jtype,1));
+      SpN = Sp(Nlj,Nmin,Nmax,dNlj);
 
-          if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+      tmp2 = VA*dN3[1]*dwjl/rjlmag;
+      f[atomj][0] -= tmp2*rjl[0];
+      f[atomj][1] -= tmp2*rjl[1];
+      f[atomj][2] -= tmp2*rjl[2];
+      f[atoml][0] += tmp2*rjl[0];
+      f[atoml][1] += tmp2*rjl[1];
+      f[atoml][2] += tmp2*rjl[2];
 
-          tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
-          f[atomi][0] -= tmp2*rik[0];
-          f[atomi][1] -= tmp2*rik[1];
-          f[atomi][2] -= tmp2*rik[2];
-          f[atomk][0] += tmp2*rik[0];
-          f[atomk][1] += tmp2*rik[1];
-          f[atomk][2] += tmp2*rik[2];
+      if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
 
-          if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
+      tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
+      f[atomj][0] -= tmp2*rjl[0];
+      f[atomj][1] -= tmp2*rjl[1];
+      f[atomj][2] -= tmp2*rjl[2];
+      f[atoml][0] += tmp2*rjl[0];
+      f[atoml][1] += tmp2*rjl[1];
+      f[atoml][2] += tmp2*rjl[2];
 
-          if (fabs(dNki)  >TOL) {
-            REBO_neighs_k = REBO_firstneigh[atomk];
-            for (n = 0; n < REBO_numneigh[atomk]; n++) {
-              atomn = REBO_neighs_k[n];
-              ntype = map[type[atomn]];
-              if (atomn !=atomi) {
-                rkn[0] = x[atomk][0]-x[atomn][0];
-                rkn[1] = x[atomk][1]-x[atomn][1];
-                rkn[2] = x[atomk][2]-x[atomn][2];
-                rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
-                Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
+      if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
 
-                tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
-                f[atomk][0] -= tmp2*rkn[0];
-                f[atomk][1] -= tmp2*rkn[1];
-                f[atomk][2] -= tmp2*rkn[2];
-                f[atomn][0] += tmp2*rkn[0];
-                f[atomn][1] += tmp2*rkn[1];
-                f[atomn][2] += tmp2*rkn[2];
+      if (fabs(dNlj) > TOL) {
+        REBO_neighs_l = REBO_firstneigh[atoml];
+        for (n = 0; n < REBO_numneigh[atoml]; n++) {
+          atomn = REBO_neighs_l[n];
+          if (atomn != atomj) {
+            ntype = map[type[atomn]];
+            rln[0] = x[atoml][0]-x[atomn][0];
+            rln[1] = x[atoml][1]-x[atomn][1];
+            rln[2] = x[atoml][2]-x[atomn][2];
+            rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
+            Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
 
-                if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
-              }
-            }
+            tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
+            f[atoml][0] -= tmp2*rln[0];
+            f[atoml][1] -= tmp2*rln[1];
+            f[atoml][2] -= tmp2*rln[2];
+            f[atomn][0] += tmp2*rln[0];
+            f[atomn][1] += tmp2*rln[1];
+            f[atomn][2] += tmp2*rln[2];
+
+            if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
           }
         }
       }
+    }
+  }
 
-      // Tij forces
+  Tij = 0.0;
+  dN3[0] = 0.0;
+  dN3[1] = 0.0;
+  dN3[2] = 0.0;
+  if (itype == 0 && jtype == 0)
+    Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3);
+  Etmp = 0.0;
 
-      REBO_neighs = REBO_firstneigh[j];
-      for (l = 0; l < REBO_numneigh[j]; l++) {
-        atoml = REBO_neighs[l];
-        if (atoml != atomi) {
-          ltype = map[type[atoml]];
-          rjl[0] = x[atomj][0]-x[atoml][0];
-          rjl[1] = x[atomj][1]-x[atoml][1];
-          rjl[2] = x[atomj][2]-x[atoml][2];
-          rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
-          wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
-          Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
-            (wjl*kronecker(jtype,1));
-          SpN = Sp(Nlj,Nmin,Nmax,dNlj);
-
-          tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
-          f[atomj][0] -= tmp2*rjl[0];
-          f[atomj][1] -= tmp2*rjl[1];
-          f[atomj][2] -= tmp2*rjl[2];
-          f[atoml][0] += tmp2*rjl[0];
-          f[atoml][1] += tmp2*rjl[1];
-          f[atoml][2] += tmp2*rjl[2];
+  if (fabs(Tij) > TOL) {
+    atom2 = atomi;
+    atom3 = atomj;
+    r32[0] = x[atom3][0]-x[atom2][0];
+    r32[1] = x[atom3][1]-x[atom2][1];
+    r32[2] = x[atom3][2]-x[atom2][2];
+    r32mag = sqrt((r32[0]*r32[0])+(r32[1]*r32[1])+(r32[2]*r32[2]));
+    r23[0] = -r32[0];
+    r23[1] = -r32[1];
+    r23[2] = -r32[2];
+    r23mag = r32mag;
+    REBO_neighs_i = REBO_firstneigh[i];
+    for (k = 0; k < REBO_numneigh[i]; k++) {
+      atomk = REBO_neighs_i[k];
+      atom1 = atomk;
+      ktype = map[type[atomk]];
+      if (atomk != atomj) {
+        r21[0] = x[atom2][0]-x[atom1][0];
+        r21[1] = x[atom2][1]-x[atom1][1];
+        r21[2] = x[atom2][2]-x[atom1][2];
+        r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
+        cos321 = -1.0*((r21[0]*r32[0])+(r21[1]*r32[1])+(r21[2]*r32[2])) /
+          (r21mag*r32mag);
+        cos321 = MIN(cos321,1.0);
+        cos321 = MAX(cos321,-1.0);
+        Sp2(cos321,thmin,thmax,dcut321);
+        sin321 = sqrt(1.0 - cos321*cos321);
+        if ((sin321 > TOL) && (r21mag > TOL)) { // XXX was sin321 != 0.0
+          sink2i = 1.0/(sin321*sin321);
+          rik2i = 1.0/(r21mag*r21mag);
+          rr = (r23mag*r23mag)-(r21mag*r21mag);
+          rjk[0] = r21[0]-r23[0];
+          rjk[1] = r21[1]-r23[1];
+          rjk[2] = r21[2]-r23[2];
+          rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
+          rijrik = 2.0*r23mag*r21mag;
+          rik2 = r21mag*r21mag;
+          dctik = (-rr+rjk2)/(rijrik*rik2);
+          dctij = (rr+rjk2)/(rijrik*r23mag*r23mag);
+          dctjk = -2.0/rijrik;
+          w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
+          rijmag = r32mag;
+          rikmag = r21mag;
+          rij2 = r32mag*r32mag;
+          rik2 = r21mag*r21mag;
+          costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
+          tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+          dtsjik = -dtsjik;
 
-          if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+          REBO_neighs_j = REBO_firstneigh[j];
+          for (l = 0; l < REBO_numneigh[j]; l++) {
+            atoml = REBO_neighs_j[l];
+            atom4 = atoml;
+            ltype = map[type[atoml]];
+            if (!(atoml == atomi || atoml == atomk)) {
+              r34[0] = x[atom3][0]-x[atom4][0];
+              r34[1] = x[atom3][1]-x[atom4][1];
+              r34[2] = x[atom3][2]-x[atom4][2];
+              r34mag = sqrt((r34[0]*r34[0])+(r34[1]*r34[1])+(r34[2]*r34[2]));
+              cos234 = (r32[0]*r34[0] + r32[1]*r34[1] + r32[2]*r34[2]) /
+                (r32mag*r34mag);
+              cos234 = MIN(cos234,1.0);
+              cos234 = MAX(cos234,-1.0);
+              sin234 = sqrt(1.0 - cos234*cos234);
 
-          tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
-          f[atomj][0] -= tmp2*rjl[0];
-          f[atomj][1] -= tmp2*rjl[1];
-          f[atomj][2] -= tmp2*rjl[2];
-          f[atoml][0] += tmp2*rjl[0];
-          f[atoml][1] += tmp2*rjl[1];
-          f[atoml][2] += tmp2*rjl[2];
+              if ((sin234 > TOL) && (r34mag > TOL)) {  // XXX was sin234 != 0.0
+                sinl2i = 1.0/(sin234*sin234);
+                rjl2i = 1.0/(r34mag*r34mag);
+                w34 = Sp(r34mag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dw34);
+                rr = (r23mag*r23mag)-(r34mag*r34mag);
+                ril[0] = r23[0]+r34[0];
+                ril[1] = r23[1]+r34[1];
+                ril[2] = r23[2]+r34[2];
+                ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
+                rijrjl = 2.0*r23mag*r34mag;
+                rjl2 = r34mag*r34mag;
+                dctjl = (-rr+ril2)/(rijrjl*rjl2);
+                dctji = (rr+ril2)/(rijrjl*r23mag*r23mag);
+                dctil = -2.0/rijrjl;
+                rjlmag = r34mag;
+                rjl2 = r34mag*r34mag;
+                costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
+                tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+                dtsijl = -dtsijl;
+                prefactor = VA*Tij;
 
-          if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+                cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
+                cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
+                cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
+                cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
+                cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
+                cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
 
-          if (fabs(dNlj) > TOL) {
-            REBO_neighs_l = REBO_firstneigh[atoml];
-            for (n = 0; n < REBO_numneigh[atoml]; n++) {
-              atomn = REBO_neighs_l[n];
-              ntype = map[type[atomn]];
-              if (atomn != atomj) {
-                rln[0] = x[atoml][0]-x[atomn][0];
-                rln[1] = x[atoml][1]-x[atomn][1];
-                rln[2] = x[atoml][2]-x[atomn][2];
-                rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
-                Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
+                cwnum = (cross321[0]*cross234[0]) +
+                  (cross321[1]*cross234[1]) + (cross321[2]*cross234[2]);
+                cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
+                om1234 = cwnum/cwnom;
+                cw = om1234;
+                Etmp += ((1.0-square(om1234))*w21*w34) *
+                  (1.0-tspjik)*(1.0-tspijl);
 
-                tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
-                f[atoml][0] -= tmp2*rln[0];
-                f[atoml][1] -= tmp2*rln[1];
-                f[atoml][2] -= tmp2*rln[2];
-                f[atomn][0] += tmp2*rln[0];
-                f[atomn][1] += tmp2*rln[1];
-                f[atomn][2] += tmp2*rln[2];
+                dt1dik = (rik2i)-(dctik*sink2i*cos321);
+                dt1djk = (-dctjk*sink2i*cos321);
+                dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
+                dt1dil = (-dctil*sinl2i*cos234);
+                dt1dij = (2.0/(r23mag*r23mag))-(dctij*sink2i*cos321) -
+                  (dctji*sinl2i*cos234);
 
-                if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
-              }
-            }
-          }
-        }
-      }
-    }
-  }
+                dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
+                dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
+                dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
 
-  return Stb;
-}
+                dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
+                dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
+                dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
 
-/* ----------------------------------------------------------------------
-   REBO forces and energy
-------------------------------------------------------------------------- */
+                dt2dij[0] = (r21[2]*cross234[1])-(r34[2]*cross321[1]) -
+                  (r21[1]*cross234[2])+(r34[1]*cross321[2]);
+                dt2dij[1] = (r21[0]*cross234[2])-(r34[0]*cross321[2]) -
+                  (r21[2]*cross234[0])+(r34[2]*cross321[0]);
+                dt2dij[2] = (r21[1]*cross234[0])-(r34[1]*cross321[0]) -
+                  (r21[0]*cross234[1])+(r34[0]*cross321[1]);
 
-void PairAIREBOOMP::FREBO_thr(int ifrom, int ito, int evflag, int eflag,
-                              int vflag_atom, double *pv0, ThrData * const thr)
-{
-  int i,j,k,m,ii,itype,jtype;
-  tagint itag,jtag;
-  double delx,dely,delz,evdwl,fpair,xtmp,ytmp,ztmp;
-  double rsq,rij,wij;
-  double Qij,Aij,alphaij,VR,pre,dVRdi,VA,term,bij,dVAdi,dVA;
-  double dwij,del[3];
-  int *ilist,*REBO_neighs;
+                aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
+                  (1.0-tspjik)*(1.0-tspijl);
+                aaa1 = -prefactor*(1.0-square(om1234)) *
+                  (1.0-tspjik)*(1.0-tspijl);
+                aaa2 = aaa1*w21*w34;
+                at2 = aa*cwnum;
 
-  evdwl = 0.0;
+                fcijpc = (-dt1dij*at2)+(aaa2*dtsjik*dctij*(1.0-tspijl)) +
+                  (aaa2*dtsijl*dctji*(1.0-tspjik));
+                fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
+                fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
+                fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
+                fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
 
-  const double * const * const x = atom->x;
-  double * const * const f = thr->get_f();
-  int *type = atom->type;
-  tagint *tag = atom->tag;
-  int nlocal = atom->nlocal;
+                F23[0] = (fcijpc*r23[0])+(aa*dt2dij[0]);
+                F23[1] = (fcijpc*r23[1])+(aa*dt2dij[1]);
+                F23[2] = (fcijpc*r23[2])+(aa*dt2dij[2]);
 
-  ilist = list->ilist;
+                F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
+                F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
+                F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
 
-  // two-body interactions from REBO neighbor list, skip half of them
+                F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
+                F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
+                F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
 
-  for (ii = ifrom; ii < ito; ii++) {
-    i = ilist[ii];
-    itag = tag[i];
-    itype = map[type[i]];
-    xtmp = x[i][0];
-    ytmp = x[i][1];
-    ztmp = x[i][2];
-    REBO_neighs = REBO_firstneigh[i];
+                F31[0] = (fcjkpc*rjk[0]);
+                F31[1] = (fcjkpc*rjk[1]);
+                F31[2] = (fcjkpc*rjk[2]);
 
-    for (k = 0; k < REBO_numneigh[i]; k++) {
-      j = REBO_neighs[k];
-      jtag = tag[j];
+                F24[0] = (fcilpc*ril[0]);
+                F24[1] = (fcilpc*ril[1]);
+                F24[2] = (fcilpc*ril[2]);
 
-      if (itag > jtag) {
-        if ((itag+jtag) % 2 == 0) continue;
-      } else if (itag < jtag) {
-        if ((itag+jtag) % 2 == 1) continue;
-      } else {
-        if (x[j][2] < ztmp) continue;
-        if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
-        if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
-      }
+                f1[0] = -F12[0]-F31[0];
+                f1[1] = -F12[1]-F31[1];
+                f1[2] = -F12[2]-F31[2];
+                f2[0] = F23[0]+F12[0]+F24[0];
+                f2[1] = F23[1]+F12[1]+F24[1];
+                f2[2] = F23[2]+F12[2]+F24[2];
+                f3[0] = -F23[0]+F34[0]+F31[0];
+                f3[1] = -F23[1]+F34[1]+F31[1];
+                f3[2] = -F23[2]+F34[2]+F31[2];
+                f4[0] = -F34[0]-F24[0];
+                f4[1] = -F34[1]-F24[1];
+                f4[2] = -F34[2]-F24[2];
 
-      jtype = map[type[j]];
+                // coordination forces
 
-      delx = x[i][0] - x[j][0];
-      dely = x[i][1] - x[j][1];
-      delz = x[i][2] - x[j][2];
-      rsq = delx*delx + dely*dely + delz*delz;
-      rij = sqrt(rsq);
-      wij = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
-      if (wij <= TOL) continue;
+                tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+                  (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
+                f2[0] -= tmp2*r21[0];
+                f2[1] -= tmp2*r21[1];
+                f2[2] -= tmp2*r21[2];
+                f1[0] += tmp2*r21[0];
+                f1[1] += tmp2*r21[1];
+                f1[2] += tmp2*r21[2];
 
-      Qij = Q[itype][jtype];
-      Aij = A[itype][jtype];
-      alphaij = alpha[itype][jtype];
+                tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+                  (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
+                f3[0] -= tmp2*r34[0];
+                f3[1] -= tmp2*r34[1];
+                f3[2] -= tmp2*r34[2];
+                f4[0] += tmp2*r34[0];
+                f4[1] += tmp2*r34[1];
+                f4[2] += tmp2*r34[2];
 
-      VR = wij*(1.0+(Qij/rij)) * Aij*exp(-alphaij*rij);
-      pre = wij*Aij * exp(-alphaij*rij);
-      dVRdi = pre * ((-alphaij)-(Qij/rsq)-(Qij*alphaij/rij));
-      dVRdi += VR/wij * dwij;
+                f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
+                f[atom1][2] += f1[2];
+                f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
+                f[atom2][2] += f2[2];
+                f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
+                f[atom3][2] += f3[2];
+                f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
+                f[atom4][2] += f4[2];
 
-      VA = dVA = 0.0;
-      for (m = 0; m < 3; m++) {
-        term = -wij * BIJc[itype][jtype][m] * exp(-Beta[itype][jtype][m]*rij);
-        VA += term;
-        dVA += -Beta[itype][jtype][m] * term;
+                if (vflag_atom) {
+                  r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
+                  r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
+                  v_tally4_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr);
+                }
+              }
+            }
+          }
+        }
       }
-      dVA += VA/wij * dwij;
-      del[0] = delx;
-      del[1] = dely;
-      del[2] = delz;
-      bij = bondorder_thr(i,j,del,rij,VA,vflag_atom,thr);
-      dVAdi = bij*dVA;
-
-      fpair = -(dVRdi+dVAdi) / rij;
-      f[i][0] += delx*fpair;
-      f[i][1] += dely*fpair;
-      f[i][2] += delz*fpair;
-      f[j][0] -= delx*fpair;
-      f[j][1] -= dely*fpair;
-      f[j][2] -= delz*fpair;
-
-      if (eflag) *pv0 += evdwl = VR + bij*VA;
-      if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
-                               evdwl,0.0,fpair,delx,dely,delz,thr);
     }
-  }
-}
-
-/* ----------------------------------------------------------------------
-   compute LJ forces and energy
-   find 3- and 4-step paths between atoms I,J via REBO neighbor lists
-------------------------------------------------------------------------- */
 
-void PairAIREBOOMP::FLJ_thr(int ifrom, int ito, int evflag, int eflag,
-                            int vflag_atom, double *pv1, ThrData * const thr)
-{
-  int i,j,k,m,ii,jj,kk,mm,jnum,itype,jtype,ktype,mtype;
-  tagint itag,jtag;
-  int atomi,atomj,atomk,atomm;
-  int testpath,npath,done;
-  double evdwl,fpair,xtmp,ytmp,ztmp;
-  double rsq,best,wik,wkm,cij,rij,dwij,dwik,dwkj,dwkm,dwmj;
-  double delij[3],rijsq,delik[3],rik,deljk[3];
-  double rkj,wkj,dC,VLJ,dVLJ,VA,Str,dStr,Stb;
-  double vdw,slw,dvdw,dslw,drij,swidth,tee,tee2;
-  double rljmin,rljmax,sigcut,sigmin,sigwid;
-  double delkm[3],rkm,deljm[3],rmj,wmj,r2inv,r6inv,scale,delscale[3];
-  int *ilist,*jlist,*numneigh,**firstneigh;
-  int *REBO_neighs_i,*REBO_neighs_k;
-  double delikS[3],deljkS[3],delkmS[3],deljmS[3],delimS[3];
-  double rikS,rkjS,rkmS,rmjS,wikS,dwikS;
-  double wkjS,dwkjS,wkmS,dwkmS,wmjS,dwmjS;
-  double fpair1,fpair2,fpair3;
-  double fi[3],fj[3],fk[3],fm[3];
+    // Tij forces now that we have Etmp
 
-  // I-J interaction from full neighbor list
-  // skip 1/2 of interactions since only consider each pair once
+    REBO_neighs = REBO_firstneigh[i];
+    for (k = 0; k < REBO_numneigh[i]; k++) {
+      atomk = REBO_neighs[k];
+      if (atomk != atomj) {
+        ktype = map[type[atomk]];
+        rik[0] = x[atomi][0]-x[atomk][0];
+        rik[1] = x[atomi][1]-x[atomk][1];
+        rik[2] = x[atomi][2]-x[atomk][2];
+        rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+        wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+        Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+          (wik*kronecker(itype,1));
+        SpN = Sp(Nki,Nmin,Nmax,dNki);
 
-  evdwl = 0.0;
-  rljmin = 0.0;
-  rljmax = 0.0;
-  sigcut = 0.0;
-  sigmin = 0.0;
-  sigwid = 0.0;
+        tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
+        f[atomi][0] -= tmp2*rik[0];
+        f[atomi][1] -= tmp2*rik[1];
+        f[atomi][2] -= tmp2*rik[2];
+        f[atomk][0] += tmp2*rik[0];
+        f[atomk][1] += tmp2*rik[1];
+        f[atomk][2] += tmp2*rik[2];
 
-  const double * const * const x = atom->x;
-  double * const * const f = thr->get_f();
-  tagint *tag = atom->tag;
-  int *type = atom->type;
-  int nlocal = atom->nlocal;
+        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-  ilist = list->ilist;
-  numneigh = list->numneigh;
-  firstneigh = list->firstneigh;
+        tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
+        f[atomi][0] -= tmp2*rik[0];
+        f[atomi][1] -= tmp2*rik[1];
+        f[atomi][2] -= tmp2*rik[2];
+        f[atomk][0] += tmp2*rik[0];
+        f[atomk][1] += tmp2*rik[1];
+        f[atomk][2] += tmp2*rik[2];
 
-  // loop over neighbors of my atoms
+        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-  for (ii = ifrom; ii < ito; ii++) {
-    i = ilist[ii];
-    itag = tag[i];
-    itype = map[type[i]];
-    atomi = i;
-    xtmp = x[i][0];
-    ytmp = x[i][1];
-    ztmp = x[i][2];
-    jlist = firstneigh[i];
-    jnum = numneigh[i];
+        if (fabs(dNki) > TOL) {
+          REBO_neighs_k = REBO_firstneigh[atomk];
+          for (n = 0; n < REBO_numneigh[atomk]; n++) {
+            atomn = REBO_neighs_k[n];
+            ntype = map[type[atomn]];
+            if (atomn != atomi) {
+              rkn[0] = x[atomk][0]-x[atomn][0];
+              rkn[1] = x[atomk][1]-x[atomn][1];
+              rkn[2] = x[atomk][2]-x[atomn][2];
+              rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
+              Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
 
-    for (jj = 0; jj < jnum; jj++) {
-      j = jlist[jj];
-      j &= NEIGHMASK;
-      jtag = tag[j];
+              tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
+              f[atomk][0] -= tmp2*rkn[0];
+              f[atomk][1] -= tmp2*rkn[1];
+              f[atomk][2] -= tmp2*rkn[2];
+              f[atomn][0] += tmp2*rkn[0];
+              f[atomn][1] += tmp2*rkn[1];
+              f[atomn][2] += tmp2*rkn[2];
 
-      if (itag > jtag) {
-        if ((itag+jtag) % 2 == 0) continue;
-      } else if (itag < jtag) {
-        if ((itag+jtag) % 2 == 1) continue;
-      } else {
-        if (x[j][2] < ztmp) continue;
-        if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
-        if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+              if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
+            }
+          }
+        }
       }
+    }
 
-      jtype = map[type[j]];
-      atomj = j;
-
-      delij[0] = xtmp - x[j][0];
-      delij[1] = ytmp - x[j][1];
-      delij[2] = ztmp - x[j][2];
-      rijsq = delij[0]*delij[0] + delij[1]*delij[1] + delij[2]*delij[2];
+    // Tij forces
 
-      // if outside of LJ cutoff, skip
-      // if outside of 4-path cutoff, best = 0.0, no need to test paths
-      // if outside of 2-path cutoff but inside 4-path cutoff,
-      //   best = 0.0, test 3-,4-paths
-      // if inside 2-path cutoff, best = wij, only test 3-,4-paths if best < 1
-      npath = testpath = done = 0;
-      best = 0.0;
+    REBO_neighs = REBO_firstneigh[j];
+    for (l = 0; l < REBO_numneigh[j]; l++) {
+      atoml = REBO_neighs[l];
+      if (atoml != atomi) {
+        ltype = map[type[atoml]];
+        rjl[0] = x[atomj][0]-x[atoml][0];
+        rjl[1] = x[atomj][1]-x[atoml][1];
+        rjl[2] = x[atomj][2]-x[atoml][2];
+        rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+        wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+        Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+          (wjl*kronecker(jtype,1));
+        SpN = Sp(Nlj,Nmin,Nmax,dNlj);
 
-      if (rijsq >= cutljsq[itype][jtype]) continue;
-      rij = sqrt(rijsq);
-      if (rij >= cut3rebo) {
-        best = 0.0;
-        testpath = 0;
-      } else if (rij >= rcmax[itype][jtype]) {
-        best = 0.0;
-        testpath = 1;
-      } else {
-        best = Sp(rij,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
-        npath = 2;
-        if (best < 1.0) testpath = 1;
-        else testpath = 0;
-      }
+        tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
+        f[atomj][0] -= tmp2*rjl[0];
+        f[atomj][1] -= tmp2*rjl[1];
+        f[atomj][2] -= tmp2*rjl[2];
+        f[atoml][0] += tmp2*rjl[0];
+        f[atoml][1] += tmp2*rjl[1];
+        f[atoml][2] += tmp2*rjl[2];
 
-      if (testpath) {
+        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
 
-        // test all 3-body paths = I-K-J
-        // I-K interactions come from atom I's REBO neighbors
-        // if wik > current best, compute wkj
-        // if best = 1.0, done
+        tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
+        f[atomj][0] -= tmp2*rjl[0];
+        f[atomj][1] -= tmp2*rjl[1];
+        f[atomj][2] -= tmp2*rjl[2];
+        f[atoml][0] += tmp2*rjl[0];
+        f[atoml][1] += tmp2*rjl[1];
+        f[atoml][2] += tmp2*rjl[2];
 
-        REBO_neighs_i = REBO_firstneigh[i];
-        for (kk = 0; kk < REBO_numneigh[i] && done==0; kk++) {
-          k = REBO_neighs_i[kk];
-          if (k == j) continue;
-          ktype = map[type[k]];
+        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
 
-          delik[0] = x[i][0] - x[k][0];
-          delik[1] = x[i][1] - x[k][1];
-          delik[2] = x[i][2] - x[k][2];
-          rsq = delik[0]*delik[0] + delik[1]*delik[1] + delik[2]*delik[2];
-          if (rsq < rcmaxsq[itype][ktype]) {
-            rik = sqrt(rsq);
-            wik = Sp(rik,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
-          } else { dwik = wik = 0.0; rikS = rik = 1.0; }
+        if (fabs(dNlj) > TOL) {
+          REBO_neighs_l = REBO_firstneigh[atoml];
+          for (n = 0; n < REBO_numneigh[atoml]; n++) {
+            atomn = REBO_neighs_l[n];
+            ntype = map[type[atomn]];
+            if (atomn !=atomj) {
+              rln[0] = x[atoml][0]-x[atomn][0];
+              rln[1] = x[atoml][1]-x[atomn][1];
+              rln[2] = x[atoml][2]-x[atomn][2];
+              rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
+              Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
 
-          if (wik > best) {
-            deljk[0] = x[j][0] - x[k][0];
-            deljk[1] = x[j][1] - x[k][1];
-            deljk[2] = x[j][2] - x[k][2];
-            rsq = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
-            if (rsq < rcmaxsq[ktype][jtype]) {
-              rkj = sqrt(rsq);
-              wkj = Sp(rkj,rcmin[ktype][jtype],rcmax[ktype][jtype],dwkj);
-              if (wik*wkj > best) {
-                best = wik*wkj;
-                npath = 3;
-                atomk = k;
-                delikS[0] = delik[0];
-                delikS[1] = delik[1];
-                delikS[2] = delik[2];
-                rikS = rik;
-                wikS = wik;
-                dwikS = dwik;
-                deljkS[0] = deljk[0];
-                deljkS[1] = deljk[1];
-                deljkS[2] = deljk[2];
-                rkjS = rkj;
-                wkjS = wkj;
-                dwkjS = dwkj;
-                if (best == 1.0) {
-                  done = 1;
-                  break;
-                }
-              }
+              tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
+              f[atoml][0] -= tmp2*rln[0];
+              f[atoml][1] -= tmp2*rln[1];
+              f[atoml][2] -= tmp2*rln[2];
+              f[atomn][0] += tmp2*rln[0];
+              f[atomn][1] += tmp2*rln[1];
+              f[atomn][2] += tmp2*rln[2];
+
+              if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
             }
+          }
+        }
+      }
+    }
+  }
 
-            // test all 4-body paths = I-K-M-J
-            // K-M interactions come from atom K's REBO neighbors
-            // if wik*wkm > current best, compute wmj
-            // if best = 1.0, done
+  bij = (0.5*(pij+pji))+piRC+(Tij*Etmp);
+  return bij;
+}
 
-            REBO_neighs_k = REBO_firstneigh[k];
-            for (mm = 0; mm < REBO_numneigh[k] && done==0; mm++) {
-              m = REBO_neighs_k[mm];
-              if (m == i || m == j) continue;
-              mtype = map[type[m]];
-              delkm[0] = x[k][0] - x[m][0];
-              delkm[1] = x[k][1] - x[m][1];
-              delkm[2] = x[k][2] - x[m][2];
-              rsq = delkm[0]*delkm[0] + delkm[1]*delkm[1] + delkm[2]*delkm[2];
-              if (rsq < rcmaxsq[ktype][mtype]) {
-                rkm = sqrt(rsq);
-                wkm = Sp(rkm,rcmin[ktype][mtype],rcmax[ktype][mtype],dwkm);
-              } else { dwkm = wkm = 0.0; rkmS = rkm = 1.0; }
+/* ----------------------------------------------------------------------
+   Bij* function
+------------------------------------------------------------------------- */
 
-              if (wik*wkm > best) {
-                deljm[0] = x[j][0] - x[m][0];
-                deljm[1] = x[j][1] - x[m][1];
-                deljm[2] = x[j][2] - x[m][2];
-                rsq = deljm[0]*deljm[0] + deljm[1]*deljm[1] +
-                  deljm[2]*deljm[2];
-                if (rsq < rcmaxsq[mtype][jtype]) {
-                  rmj = sqrt(rsq);
-                  wmj = Sp(rmj,rcmin[mtype][jtype],rcmax[mtype][jtype],dwmj);
-                  if (wik*wkm*wmj > best) {
-                    best = wik*wkm*wmj;
-                    npath = 4;
-                    atomk = k;
-                    delikS[0] = delik[0];
-                    delikS[1] = delik[1];
-                    delikS[2] = delik[2];
-                    rikS = rik;
-                    wikS = wik;
-                    dwikS = dwik;
-                    atomm = m;
-                    delkmS[0] = delkm[0];
-                    delkmS[1] = delkm[1];
-                    delkmS[2] = delkm[2];
-                    rkmS = rkm;
-                    wkmS = wkm;
-                    dwkmS = dwkm;
-                    deljmS[0] = deljm[0];
-                    deljmS[1] = deljm[1];
-                    deljmS[2] = deljm[2];
-                    rmjS = rmj;
-                    wmjS = wmj;
-                    dwmjS = dwmj;
-                    if (best == 1.0) {
-                      done = 1;
-                      break;
-                    }
-                  }
-                }
+double PairAIREBOOMP::bondorderLJ_thr(int i, int j, double rij[3], double rijmag,
+                                      double VA, double rij0[3], double rij0mag,
+                                      int vflag_atom, ThrData * const thr)
+{
+  int k,n,l,atomk,atoml,atomn,atom1,atom2,atom3,atom4;
+  int atomi,atomj,itype,jtype,ktype,ltype,ntype;
+  double rik[3], rjl[3], rkn[3],rknmag,dNki;
+  double NijC,NijH,NjiC,NjiH,wik,dwik,dwkn,wjl;
+  double rikmag,rjlmag,cosjik,cosijl,g,tmp2,tmp3;
+  double Etmp,pij,tmp,wij,dwij,NconjtmpI,NconjtmpJ;
+  double Nki,Nlj,dS,lamdajik,lamdaijl,dgdc,dgdN,pji,Nijconj,piRC;
+  double dcosjikdri[3],dcosijldri[3],dcosjikdrk[3];
+  double dN2[2],dN3[3];
+  double dcosijldrj[3],dcosijldrl[3],dcosjikdrj[3],dwjl;
+  double Tij,crosskij[3],crosskijmag;
+  double crossijl[3],crossijlmag,omkijl;
+  double tmppij,tmppji,dN2PIJ[2],dN2PJI[2],dN3piRC[3],dN3Tij[3];
+  double bij,tmp3pij,tmp3pji,Stb,dStb;
+  double r32[3],r32mag,cos321;
+  double om1234,rln[3];
+  double rlnmag,dwln,r23[3],r23mag,r21[3],r21mag;
+  double w21,dw21,r34[3],r34mag,cos234,w34,dw34;
+  double cross321[3],cross234[3],prefactor,SpN;
+  double fcijpc,fcikpc,fcjlpc,fcjkpc,fcilpc;
+  double dt2dik[3],dt2djl[3],dt2dij[3],aa,aaa1,aaa2,at2,cw,cwnum,cwnom;
+  double sin321,sin234,rr,rijrik,rijrjl,rjk2,rik2,ril2,rjl2;
+  double dctik,dctjk,dctjl,dctij,dctji,dctil,rik2i,rjl2i,sink2i,sinl2i;
+  double rjk[3],ril[3],dt1dik,dt1djk,dt1djl,dt1dil,dt1dij;
+  double dNlj;
+  double PijS,PjiS;
+  double rij2,tspjik,dtsjik,tspijl,dtsijl,costmp;
+  int *REBO_neighs,*REBO_neighs_i,*REBO_neighs_j,*REBO_neighs_k,*REBO_neighs_l;
+  double F12[3],F23[3],F34[3],F31[3],F24[3];
+  double fi[3],fj[3],fk[3],fl[3],f1[3],f2[3],f3[3],f4[4];
+  double rji[3],rki[3],rlj[3],r13[3],r43[3];
+  double realrij[3], realrijmag;
+  double rjkmag, rilmag, dctdjk, dctdik, dctdil, dctdjl;
+  double fjk[3], fil[3], rijmbr;
+
+  const double * const * const x = atom->x;
+  double * const * const f = thr->get_f();
+  const int * const type = atom->type;
+
+  atomi = i;
+  atomj = j;
+  itype = map[type[atomi]];
+  jtype = map[type[atomj]];
+  wij = Sp(rij0mag,rcmin[itype][jtype],rcmax[itype][jtype],dwij);
+  NijC = nC[atomi]-(wij*kronecker(jtype,0));
+  NijH = nH[atomi]-(wij*kronecker(jtype,1));
+  NjiC = nC[atomj]-(wij*kronecker(itype,0));
+  NjiH = nH[atomj]-(wij*kronecker(itype,1));
+
+  bij = 0.0;
+  tmp = 0.0;
+  tmp2 = 0.0;
+  tmp3 = 0.0;
+  dgdc = 0.0;
+  dgdN = 0.0;
+  NconjtmpI = 0.0;
+  NconjtmpJ = 0.0;
+  Etmp = 0.0;
+  Stb = 0.0;
+  dStb = 0.0;
+
+  realrij[0] = x[atomi][0] - x[atomj][0];
+  realrij[1] = x[atomi][1] - x[atomj][1];
+  realrij[2] = x[atomi][2] - x[atomj][2];
+  realrijmag = sqrt(realrij[0] * realrij[0] + realrij[1] * realrij[1] 
+                                            + realrij[2] * realrij[2]);
+
+  REBO_neighs = REBO_firstneigh[i];
+  for (k = 0; k < REBO_numneigh[i]; k++) {
+    atomk = REBO_neighs[k];
+    if (atomk != atomj) {
+      ktype = map[type[atomk]];
+      rik[0] = x[atomi][0]-x[atomk][0];
+      rik[1] = x[atomi][1]-x[atomk][1];
+      rik[2] = x[atomi][2]-x[atomk][2];
+      rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+      lamdajik = 4.0*kronecker(itype,1) *
+        ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
+      wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dS);
+      Nki = nC[atomk]-(wik*kronecker(itype,0)) +
+        nH[atomk]-(wik*kronecker(itype,1));
+      cosjik = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
+        (rijmag*rikmag);
+      cosjik = MIN(cosjik,1.0);
+      cosjik = MAX(cosjik,-1.0);
+
+      // evaluate splines g and derivatives dg
+
+      g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
+      Etmp += (wik*g*exp(lamdajik));
+      tmp3 += (wik*dgdN*exp(lamdajik));
+      NconjtmpI = NconjtmpI+(kronecker(ktype,0)*wik*Sp(Nki,Nmin,Nmax,dS));
+    }
+  }
+
+  PijS = 0.0;
+  dN2PIJ[0] = 0.0;
+  dN2PIJ[1] = 0.0;
+  PijS = PijSpline(NijC,NijH,itype,jtype,dN2PIJ);
+  pij = 1.0/sqrt(1.0+Etmp+PijS);
+  tmppij = -.5*pij*pij*pij;
+  tmp3pij = tmp3;
+  tmp = 0.0;
+  tmp2 = 0.0;
+  tmp3 = 0.0;
+  Etmp = 0.0;
+
+  REBO_neighs = REBO_firstneigh[j];
+  for (l = 0; l < REBO_numneigh[j]; l++) {
+    atoml = REBO_neighs[l];
+    if (atoml != atomi) {
+      ltype = map[type[atoml]];
+      rjl[0] = x[atomj][0]-x[atoml][0];
+      rjl[1] = x[atomj][1]-x[atoml][1];
+      rjl[2] = x[atomj][2]-x[atoml][2];
+      rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+      lamdaijl = 4.0*kronecker(jtype,1) *
+        ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
+      wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dS);
+      Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+        (wjl*kronecker(jtype,1));
+      cosijl = -1.0*((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
+        (rijmag*rjlmag);
+      cosijl = MIN(cosijl,1.0);
+      cosijl = MAX(cosijl,-1.0);
+
+      // evaluate splines g and derivatives dg
+
+      g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
+      Etmp += (wjl*g*exp(lamdaijl));
+      tmp3 += (wjl*dgdN*exp(lamdaijl));
+      NconjtmpJ = NconjtmpJ+(kronecker(ltype,0)*wjl*Sp(Nlj,Nmin,Nmax,dS));
+    }
+  }
+
+  PjiS = 0.0;
+  dN2PJI[0] = 0.0;
+  dN2PJI[1] = 0.0;
+  PjiS = PijSpline(NjiC,NjiH,jtype,itype,dN2PJI);
+  pji = 1.0/sqrt(1.0+Etmp+PjiS);
+  tmppji = -.5*pji*pji*pji;
+  tmp3pji = tmp3;
+
+  // evaluate Nij conj
+
+  Nijconj = 1.0+(NconjtmpI*NconjtmpI)+(NconjtmpJ*NconjtmpJ);
+  piRC = piRCSpline(NijC+NijH,NjiC+NjiH,Nijconj,itype,jtype,dN3piRC);
+  Tij = 0.0;
+  dN3Tij[0] = 0.0;
+  dN3Tij[1] = 0.0;
+  dN3Tij[2] = 0.0;
+  if (itype == 0 && jtype == 0)
+    Tij=TijSpline((NijC+NijH),(NjiC+NjiH),Nijconj,dN3Tij);
+
+  Etmp = 0.0;
+  if (fabs(Tij) > TOL) {
+    REBO_neighs_i = REBO_firstneigh[i];
+    for (k = 0; k < REBO_numneigh[i]; k++) {
+      atomk = REBO_neighs_i[k];
+      ktype = map[type[atomk]];
+      if (atomk != atomj) {
+        rik[0] = x[atomi][0]-x[atomk][0];
+        rik[1] = x[atomi][1]-x[atomk][1];
+        rik[2] = x[atomi][2]-x[atomk][2];
+        rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+        cos321 = ((rij[0]*rik[0])+(rij[1]*rik[1])+(rij[2]*rik[2])) /
+          (rijmag*rikmag);
+        cos321 = MIN(cos321,1.0);
+        cos321 = MAX(cos321,-1.0);
+
+        rjk[0] = rik[0]-rij[0];
+        rjk[1] = rik[1]-rij[1];
+        rjk[2] = rik[2]-rij[2];
+        rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
+        rij2 = rijmag*rijmag;
+        rik2 = rikmag*rikmag;
+        costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
+        tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+
+        if (sqrt(1.0 - cos321*cos321) > sqrt(TOL)) {
+          wik = Sp(rikmag,rcmin[itype][ktype],rcmaxp[itype][ktype],dwik);
+          REBO_neighs_j = REBO_firstneigh[j];
+          for (l = 0; l < REBO_numneigh[j]; l++) {
+            atoml = REBO_neighs_j[l];
+            ltype = map[type[atoml]];
+            if (!(atoml == atomi || atoml == atomk)) {
+              rjl[0] = x[atomj][0]-x[atoml][0];
+              rjl[1] = x[atomj][1]-x[atoml][1];
+              rjl[2] = x[atomj][2]-x[atoml][2];
+              rjlmag = sqrt(rjl[0]*rjl[0] + rjl[1]*rjl[1] + rjl[2]*rjl[2]);
+              cos234 = -((rij[0]*rjl[0])+(rij[1]*rjl[1])+(rij[2]*rjl[2])) /
+                (rijmag*rjlmag);
+              cos234 = MIN(cos234,1.0);
+              cos234 = MAX(cos234,-1.0);
+
+              ril[0] = rij[0]+rjl[0];
+              ril[1] = rij[1]+rjl[1];
+              ril[2] = rij[2]+rjl[2];
+              ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
+              rjl2 = rjlmag*rjlmag;
+              costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
+              tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+
+              if (sqrt(1.0 - cos234*cos234) > sqrt(TOL)) {
+                wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmaxp[jtype][ltype],dS);
+                crosskij[0] = (rij[1]*rik[2]-rij[2]*rik[1]);
+                crosskij[1] = (rij[2]*rik[0]-rij[0]*rik[2]);
+                crosskij[2] = (rij[0]*rik[1]-rij[1]*rik[0]);
+                crosskijmag = sqrt(crosskij[0]*crosskij[0] +
+                                   crosskij[1]*crosskij[1] +
+                                   crosskij[2]*crosskij[2]);
+                crossijl[0] = (rij[1]*rjl[2]-rij[2]*rjl[1]);
+                crossijl[1] = (rij[2]*rjl[0]-rij[0]*rjl[2]);
+                crossijl[2] = (rij[0]*rjl[1]-rij[1]*rjl[0]);
+                crossijlmag = sqrt(crossijl[0]*crossijl[0] +
+                                   crossijl[1]*crossijl[1] +
+                                   crossijl[2]*crossijl[2]);
+                omkijl = -1.0*(((crosskij[0]*crossijl[0]) +
+                                (crosskij[1]*crossijl[1]) +
+                                (crosskij[2]*crossijl[2])) /
+                               (crosskijmag*crossijlmag));
+                Etmp += ((1.0-square(omkijl))*wik*wjl) *
+                  (1.0-tspjik)*(1.0-tspijl);
               }
             }
           }
         }
       }
+    }
+  }
 
-      cij = 1.0 - best;
-      if (cij == 0.0) continue;
-
-      // compute LJ forces and energy
-
-      sigwid = 0.84;
-      sigcut = 3.0;
-      sigmin = sigcut - sigwid;
-
-      rljmin = sigma[itype][jtype];
-      rljmax = sigcut * rljmin;
-      rljmin = sigmin * rljmin;
-
-      if (rij > rljmax) {
-        slw = 0.0;
-        dslw = 0.0;
-      } else if (rij > rljmin) {
-        drij = rij - rljmin;
-        swidth = rljmax - rljmin;
-        tee = drij / swidth;
-        tee2 = tee*tee;
-        slw = 1.0 - tee2 * (3.0 - 2.0 * tee);
-        dslw = 6.0 * tee * (1.0 - tee) / rij / swidth;
-      } else {
-        slw = 1.0;
-        dslw = 0.0;
-      }
-
-      if (morseflag) {
-
-        const double exr = exp(-rij*lj4[itype][jtype]);
-        vdw = lj1[itype][jtype]*exr*(lj2[itype][jtype]*exr - 2);
-        dvdw = lj3[itype][jtype]*exr*(1-lj2[itype][jtype]*exr);
+  bij = (.5*(pij+pji))+piRC+(Tij*Etmp);
+  Stb = Sp2(bij,bLJmin[itype][jtype],bLJmax[itype][jtype],dStb);
+  VA = VA*dStb;
 
-      } else {
+  if (dStb != 0.0) {
+    tmp = tmppij;
+    dN2[0] = dN2PIJ[0];
+    dN2[1] = dN2PIJ[1];
+    tmp3 = tmp3pij;
 
-        r2inv = 1.0/rijsq;
-        r6inv = r2inv*r2inv*r2inv;
+    // pij forces
 
-        vdw = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]);
-        dvdw = -r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]) / rij;
-      }
+    REBO_neighs_i = REBO_firstneigh[i];
+    for (k = 0; k < REBO_numneigh[i]; k++) {
+      atomk = REBO_neighs_i[k];
+      ktype = map[type[atomk]];
+      if (atomk != atomj) {
+        lamdajik = 0.0;
+        rik[0] = x[atomi][0]-x[atomk][0];
+        rik[1] = x[atomi][1]-x[atomk][1];
+        rik[2] = x[atomi][2]-x[atomk][2];
+        rikmag = sqrt(rik[0]*rik[0] + rik[1]*rik[1] + rik[2]*rik[2]);
+        lamdajik = 4.0*kronecker(itype,1) *
+          ((rho[ktype][1]-rikmag)-(rho[jtype][1]-rijmag));
+        wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+        rjk[0] = rik[0] - rij[0];
+        rjk[1] = rik[1] - rij[1];
+        rjk[2] = rik[2] - rij[2];
+        rjkmag = sqrt(rjk[0] * rjk[0] + rjk[1] * rjk[1] + rjk[2] * rjk[2]);
+        rijrik = 2 * rijmag * rikmag;
+        rr = rijmag * rijmag - rikmag * rikmag;
+        cosjik = (rijmag * rijmag + rikmag * rikmag - rjkmag * rjkmag) / rijrik;
+        cosjik = MIN(cosjik,1.0);
+        cosjik = MAX(cosjik,-1.0);
+        dctdjk = -2 / rijrik;
+        dctdik = (-rr + rjkmag * rjkmag) / (rijrik * rikmag * rikmag);
+        // evaluate splines g and derivatives dg
 
-      // VLJ now becomes vdw * slw, derivaties, etc.
+        g = gSpline(cosjik,(NijC+NijH),itype,&dgdc,&dgdN);
 
-      VLJ = vdw * slw;
-      dVLJ = dvdw * slw + vdw * dslw;
+        tmp2 = VA*.5*(tmp*wik*dgdc*exp(lamdajik));
 
-      Str = Sp2(rij,rcLJmin[itype][jtype],rcLJmax[itype][jtype],dStr);
-      VA = Str*cij*VLJ;
-      if (Str > 0.0) {
-        scale = rcmin[itype][jtype] / rij;
-        delscale[0] = scale * delij[0];
-        delscale[1] = scale * delij[1];
-        delscale[2] = scale * delij[2];
-        Stb = bondorderLJ_thr(i,j,delscale,rcmin[itype][jtype],VA,
-                              delij,rij,vflag_atom,thr);
-      } else Stb = 0.0;
+        fi[0] = -tmp2 * dctdik * rik[0];
+        fi[1] = -tmp2 * dctdik * rik[1];
+        fi[2] = -tmp2 * dctdik * rik[2];
+        fk[0] =  tmp2 * dctdik * rik[0];
+        fk[1] =  tmp2 * dctdik * rik[1];
+        fk[2] =  tmp2 * dctdik * rik[2];
+        fj[0] = 0;
+        fj[1] = 0;
+        fj[2] = 0;
+        fjk[0] = -tmp2 * dctdjk * rjk[0];
+        fjk[1] = -tmp2 * dctdjk * rjk[1];
+        fjk[2] = -tmp2 * dctdjk * rjk[2];
+        fi[0] += fjk[0];
+        fi[1] += fjk[1];
+        fi[2] += fjk[2];
+        fk[0] -= fjk[0];
+        fk[1] -= fjk[1];
+        fk[2] -= fjk[2];
+        rijmbr = rcmin[itype][jtype] / realrijmag;
+        fj[0] += rijmbr * (fjk[0] - (realrij[0] * realrij[0] * fjk[0] + realrij[0] * realrij[1] * fjk[1] + realrij[0] * realrij[2] * fjk[2]) / (realrijmag * realrijmag));
+        fj[1] += rijmbr * (fjk[1] - (realrij[1] * realrij[0] * fjk[0] + realrij[1] * realrij[1] * fjk[1] + realrij[1] * realrij[2] * fjk[2]) / (realrijmag * realrijmag));
+        fj[2] += rijmbr * (fjk[2] - (realrij[2] * realrij[0] * fjk[0] + realrij[2] * realrij[1] * fjk[1] + realrij[2] * realrij[2] * fjk[2]) / (realrijmag * realrijmag));
+        fi[0] -= rijmbr * (fjk[0] - (realrij[0] * realrij[0] * fjk[0] + realrij[0] * realrij[1] * fjk[1] + realrij[0] * realrij[2] * fjk[2]) / (realrijmag * realrijmag));
+        fi[1] -= rijmbr * (fjk[1] - (realrij[1] * realrij[0] * fjk[0] + realrij[1] * realrij[1] * fjk[1] + realrij[1] * realrij[2] * fjk[2]) / (realrijmag * realrijmag));
+        fi[2] -= rijmbr * (fjk[2] - (realrij[2] * realrij[0] * fjk[0] + realrij[2] * realrij[1] * fjk[1] + realrij[2] * realrij[2] * fjk[2]) / (realrijmag * realrijmag));
 
-      fpair = -(dStr * (Stb*cij*VLJ - cij*VLJ) +
-                dVLJ * (Str*Stb*cij + cij - Str*cij)) / rij;
+        tmp2 = VA*.5*(tmp*wik*g*exp(lamdajik)*4.0*kronecker(itype,1));
+        fi[0] += tmp2*(rik[0]/rikmag);
+        fi[1] += tmp2*(rik[1]/rikmag);
+        fi[2] += tmp2*(rik[2]/rikmag);
+        fk[0] -= tmp2*(rik[0]/rikmag);
+        fk[1] -= tmp2*(rik[1]/rikmag);
+        fk[2] -= tmp2*(rik[2]/rikmag);
 
-      f[i][0] += delij[0]*fpair;
-      f[i][1] += delij[1]*fpair;
-      f[i][2] += delij[2]*fpair;
-      f[j][0] -= delij[0]*fpair;
-      f[j][1] -= delij[1]*fpair;
-      f[j][2] -= delij[2]*fpair;
+        // coordination forces
 
-      if (eflag) *pv1 += evdwl = VA*Stb + (1.0-Str)*cij*VLJ;
-      if (evflag) ev_tally_thr(this,i,j,nlocal,/* newton_pair */ 1,
-                               evdwl,0.0,fpair,delij[0],delij[1],delij[2],thr);
+        // dwik forces
 
-      if (cij < 1.0) {
-        dC = Str*Stb*VLJ + (1.0-Str)*VLJ;
-        if (npath == 2) {
-          fpair = dC*dwij / rij;
-          f[atomi][0] += delij[0]*fpair;
-          f[atomi][1] += delij[1]*fpair;
-          f[atomi][2] += delij[2]*fpair;
-          f[atomj][0] -= delij[0]*fpair;
-          f[atomj][1] -= delij[1]*fpair;
-          f[atomj][2] -= delij[2]*fpair;
+        tmp2 = VA*.5*(tmp*dwik*g*exp(lamdajik))/rikmag;
+        fi[0] -= tmp2*rik[0];
+        fi[1] -= tmp2*rik[1];
+        fi[2] -= tmp2*rik[2];
+        fk[0] += tmp2*rik[0];
+        fk[1] += tmp2*rik[1];
+        fk[2] += tmp2*rik[2];
 
-          if (vflag_atom) v_tally2_thr(atomi,atomj,fpair,delij,thr);
+        // PIJ forces
 
-        } else if (npath == 3) {
-          fpair1 = dC*dwikS*wkjS / rikS;
-          fi[0] = delikS[0]*fpair1;
-          fi[1] = delikS[1]*fpair1;
-          fi[2] = delikS[2]*fpair1;
-          fpair2 = dC*wikS*dwkjS / rkjS;
-          fj[0] = deljkS[0]*fpair2;
-          fj[1] = deljkS[1]*fpair2;
-          fj[2] = deljkS[2]*fpair2;
+        tmp2 = VA*.5*(tmp*dN2[ktype]*dwik)/rikmag;
+        fi[0] -= tmp2*rik[0];
+        fi[1] -= tmp2*rik[1];
+        fi[2] -= tmp2*rik[2];
+        fk[0] += tmp2*rik[0];
+        fk[1] += tmp2*rik[1];
+        fk[2] += tmp2*rik[2];
 
-          f[atomi][0] += fi[0];
-          f[atomi][1] += fi[1];
-          f[atomi][2] += fi[2];
-          f[atomj][0] += fj[0];
-          f[atomj][1] += fj[1];
-          f[atomj][2] += fj[2];
-          f[atomk][0] -= fi[0] + fj[0];
-          f[atomk][1] -= fi[1] + fj[1];
-          f[atomk][2] -= fi[2] + fj[2];
+        // dgdN forces
 
-          if (vflag_atom)
-            v_tally3_thr(atomi,atomj,atomk,fi,fj,delikS,deljkS,thr);
+        tmp2 = VA*.5*(tmp*tmp3*dwik)/rikmag;
+        fi[0] -= tmp2*rik[0];
+        fi[1] -= tmp2*rik[1];
+        fi[2] -= tmp2*rik[2];
+        fk[0] += tmp2*rik[0];
+        fk[1] += tmp2*rik[1];
+        fk[2] += tmp2*rik[2];
 
-        } else if (npath == 4) {
-          fpair1 = dC*dwikS*wkmS*wmjS / rikS;
-          fi[0] = delikS[0]*fpair1;
-          fi[1] = delikS[1]*fpair1;
-          fi[2] = delikS[2]*fpair1;
+        f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+        f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+        f[atomk][0] += fk[0]; f[atomk][1] += fk[1]; f[atomk][2] += fk[2];
 
-          fpair2 = dC*wikS*dwkmS*wmjS / rkmS;
-          fk[0] = delkmS[0]*fpair2 - fi[0];
-          fk[1] = delkmS[1]*fpair2 - fi[1];
-          fk[2] = delkmS[2]*fpair2 - fi[2];
+        if (vflag_atom) {
+          rji[0] = -rij[0]; rji[1] = -rij[1]; rji[2] = -rij[2];
+          rki[0] = -rik[0]; rki[1] = -rik[1]; rki[2] = -rik[2];
+          v_tally3_thr(atomi,atomj,atomk,fj,fk,rji,rki,thr);
+        }
+      }
+    }
 
-          fpair3 = dC*wikS*wkmS*dwmjS / rmjS;
-          fj[0] = deljmS[0]*fpair3;
-          fj[1] = deljmS[1]*fpair3;
-          fj[2] = deljmS[2]*fpair3;
+    tmp = tmppji;
+    tmp3 = tmp3pji;
+    dN2[0] = dN2PJI[0];
+    dN2[1] = dN2PJI[1];
+    REBO_neighs  =  REBO_firstneigh[j];
+    for (l = 0; l < REBO_numneigh[j]; l++) {
+      atoml = REBO_neighs[l];
+      if (atoml !=atomi) {
+        ltype = map[type[atoml]];
+        rjl[0] = x[atomj][0]-x[atoml][0];
+        rjl[1] = x[atomj][1]-x[atoml][1];
+        rjl[2] = x[atomj][2]-x[atoml][2];
+        rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+        lamdaijl = 4.0*kronecker(jtype,1) *
+          ((rho[ltype][1]-rjlmag)-(rho[itype][1]-rijmag));
+        wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+        ril[0] = rij[0] + rjl[0];
+        ril[1] = rij[1] + rjl[1];
+        ril[2] = rij[2] + rjl[2];
+        rilmag = sqrt(ril[0] * ril[0] + ril[1] * ril[1] + ril[2] * ril[2]);
+        rijrjl = 2 * rijmag * rjlmag;
+        rr = rijmag * rijmag - rjlmag * rjlmag;
+        cosijl = (rijmag * rijmag + rjlmag * rjlmag - rilmag * rilmag) / rijrjl;
+        cosijl = MIN(cosijl,1.0);
+        cosijl = MAX(cosijl,-1.0);
+        dctdil = -2 / rijrjl;
+        dctdjl = (-rr + rilmag * rilmag) / (rijrjl * rjlmag * rjlmag);
 
-          fm[0] = -delkmS[0]*fpair2 - fj[0];
-          fm[1] = -delkmS[1]*fpair2 - fj[1];
-          fm[2] = -delkmS[2]*fpair2 - fj[2];
+        // evaluate splines g and derivatives dg
 
-          f[atomi][0] += fi[0];
-          f[atomi][1] += fi[1];
-          f[atomi][2] += fi[2];
-          f[atomj][0] += fj[0];
-          f[atomj][1] += fj[1];
-          f[atomj][2] += fj[2];
-          f[atomk][0] += fk[0];
-          f[atomk][1] += fk[1];
-          f[atomk][2] += fk[2];
-          f[atomm][0] += fm[0];
-          f[atomm][1] += fm[1];
-          f[atomm][2] += fm[2];
+        g = gSpline(cosijl,NjiC+NjiH,jtype,&dgdc,&dgdN);
+        tmp2 = VA*.5*(tmp*wjl*dgdc*exp(lamdaijl));
+        fj[0] = -tmp2 * dctdjl * rjl[0];
+        fj[1] = -tmp2 * dctdjl * rjl[1];
+        fj[2] = -tmp2 * dctdjl * rjl[2];
+        fl[0] =  tmp2 * dctdjl * rjl[0];
+        fl[1] =  tmp2 * dctdjl * rjl[1];
+        fl[2] =  tmp2 * dctdjl * rjl[2];
+        fi[0] = 0;
+        fi[1] = 0;
+        fi[2] = 0;
+        fil[0] = -tmp2 * dctdil * ril[0];
+        fil[1] = -tmp2 * dctdil * ril[1];
+        fil[2] = -tmp2 * dctdil * ril[2];
+        fj[0] += fil[0];
+        fj[1] += fil[1];
+        fj[2] += fil[2];
+        fl[0] -= fil[0];
+        fl[1] -= fil[1];
+        fl[2] -= fil[2];
+        rijmbr = rcmin[itype][jtype] / realrijmag;
+        fi[0] += rijmbr * (fil[0] - (realrij[0] * realrij[0] * fil[0] + realrij[0] * realrij[1] * fil[1] + realrij[0] * realrij[2] * fil[2]) / (realrijmag * realrijmag));
+        fi[1] += rijmbr * (fil[1] - (realrij[1] * realrij[0] * fil[0] + realrij[1] * realrij[1] * fil[1] + realrij[1] * realrij[2] * fil[2]) / (realrijmag * realrijmag));
+        fi[2] += rijmbr * (fil[2] - (realrij[2] * realrij[0] * fil[0] + realrij[2] * realrij[1] * fil[1] + realrij[2] * realrij[2] * fil[2]) / (realrijmag * realrijmag));
+        fj[0] -= rijmbr * (fil[0] - (realrij[0] * realrij[0] * fil[0] + realrij[0] * realrij[1] * fil[1] + realrij[0] * realrij[2] * fil[2]) / (realrijmag * realrijmag));
+        fj[1] -= rijmbr * (fil[1] - (realrij[1] * realrij[0] * fil[0] + realrij[1] * realrij[1] * fil[1] + realrij[1] * realrij[2] * fil[2]) / (realrijmag * realrijmag));
+        fj[2] -= rijmbr * (fil[2] - (realrij[2] * realrij[0] * fil[0] + realrij[2] * realrij[1] * fil[1] + realrij[2] * realrij[2] * fil[2]) / (realrijmag * realrijmag));
 
-          if (vflag_atom) {
-            delimS[0] = delikS[0] + delkmS[0];
-            delimS[1] = delikS[1] + delkmS[1];
-            delimS[2] = delikS[2] + delkmS[2];
-            v_tally4_thr(atomi,atomj,atomk,atomm,fi,fj,fk,delimS,deljmS,delkmS,thr);
-          }
-        }
-      }
-    }
-  }
-}
+        tmp2 = VA*.5*(tmp*wjl*g*exp(lamdaijl)*4.0*kronecker(jtype,1));
+        fj[0] += tmp2*(rjl[0]/rjlmag);
+        fj[1] += tmp2*(rjl[1]/rjlmag);
+        fj[2] += tmp2*(rjl[2]/rjlmag);
+        fl[0] -= tmp2*(rjl[0]/rjlmag);
+        fl[1] -= tmp2*(rjl[1]/rjlmag);
+        fl[2] -= tmp2*(rjl[2]/rjlmag);
 
-/* ----------------------------------------------------------------------
-   torsional forces and energy
-------------------------------------------------------------------------- */
+         // coordination forces
+        // dwik forces
 
-void PairAIREBOOMP::TORSION_thr(int ifrom, int ito, int evflag, int eflag,
-                                double *pv2, ThrData * const thr)
-{
-  int i,j,k,l,ii;
-  tagint itag,jtag;
-  double evdwl,fpair,xtmp,ytmp,ztmp;
-  double cos321;
-  double w21,dw21,cos234,w34,dw34;
-  double cross321[3],cross321mag,cross234[3],cross234mag;
-  double w23,dw23,cw2,ekijl,Ec;
-  double cw,cwnum,cwnom;
-  double rij,rij2,rik,rjl,tspjik,dtsjik,tspijl,dtsijl,costmp,fcpc;
-  double sin321,sin234,rjk2,rik2,ril2,rjl2;
-  double rjk,ril;
-  double Vtors;
-  double dndij[3],tmpvec[3],dndik[3],dndjl[3];
-  double dcidij,dcidik,dcidjk,dcjdji,dcjdjl,dcjdil;
-  double dsidij,dsidik,dsidjk,dsjdji,dsjdjl,dsjdil;
-  double dxidij,dxidik,dxidjk,dxjdji,dxjdjl,dxjdil;
-  double ddndij,ddndik,ddndjk,ddndjl,ddndil,dcwddn,dcwdn,dvpdcw,Ftmp[3];
-  double del32[3],rsq,r32,del23[3],del21[3],r21;
-  double deljk[3],del34[3],delil[3],delkl[3],r23,r34;
-  double fi[3],fj[3],fk[3],fl[3];
-  int itype,jtype,ktype,ltype,kk,ll,jj;
-  int *ilist,*REBO_neighs_i,*REBO_neighs_j;
+        tmp2 = VA*.5*(tmp*dwjl*g*exp(lamdaijl))/rjlmag;
+        fj[0] -= tmp2*rjl[0];
+        fj[1] -= tmp2*rjl[1];
+        fj[2] -= tmp2*rjl[2];
+        fl[0] += tmp2*rjl[0];
+        fl[1] += tmp2*rjl[1];
+        fl[2] += tmp2*rjl[2];
 
-  const double * const * const x = atom->x;
-  double * const * const f = thr->get_f();
-  int *type = atom->type;
-  tagint *tag = atom->tag;
+        // PIJ forces
 
-  ilist = list->ilist;
+        tmp2 = VA*.5*(tmp*dN2[ltype]*dwjl)/rjlmag;
+        fj[0] -= tmp2*rjl[0];
+        fj[1] -= tmp2*rjl[1];
+        fj[2] -= tmp2*rjl[2];
+        fl[0] += tmp2*rjl[0];
+        fl[1] += tmp2*rjl[1];
+        fl[2] += tmp2*rjl[2];
 
-  for (ii = ifrom; ii < ito; ii++) {
-    i = ilist[ii];
-    itag = tag[i];
-    itype = map[type[i]];
-    if (itype != 0) continue;
-    xtmp = x[i][0];
-    ytmp = x[i][1];
-    ztmp = x[i][2];
-    REBO_neighs_i = REBO_firstneigh[i];
+        // dgdN forces
 
-    for (jj = 0; jj < REBO_numneigh[i]; jj++) {
-      j = REBO_neighs_i[jj];
-      jtag = tag[j];
+        tmp2=VA*.5*(tmp*tmp3*dwjl)/rjlmag;
+        fj[0] -= tmp2*rjl[0];
+        fj[1] -= tmp2*rjl[1];
+        fj[2] -= tmp2*rjl[2];
+        fl[0] += tmp2*rjl[0];
+        fl[1] += tmp2*rjl[1];
+        fl[2] += tmp2*rjl[2];
 
-      if (itag > jtag) {
-        if ((itag+jtag) % 2 == 0) continue;
-      } else if (itag < jtag) {
-        if ((itag+jtag) % 2 == 1) continue;
-      } else {
-        if (x[j][2] < ztmp) continue;
-        if (x[j][2] == ztmp && x[j][1] < ytmp) continue;
-        if (x[j][2] == ztmp && x[j][1] == ytmp && x[j][0] < xtmp) continue;
+        f[atomi][0] += fi[0]; f[atomi][1] += fi[1]; f[atomi][2] += fi[2];
+        f[atomj][0] += fj[0]; f[atomj][1] += fj[1]; f[atomj][2] += fj[2];
+        f[atoml][0] += fl[0]; f[atoml][1] += fl[1]; f[atoml][2] += fl[2];
+
+        if (vflag_atom) {
+          rlj[0] = -rjl[0]; rlj[1] = -rjl[1]; rlj[2] = -rjl[2];
+          v_tally3_thr(atomi,atomj,atoml,fi,fl,rij,rlj,thr);
+        }
       }
+    }
 
-      jtype = map[type[j]];
-      if (jtype != 0) continue;
+    // piRC forces
 
-      del32[0] = x[j][0]-x[i][0];
-      del32[1] = x[j][1]-x[i][1];
-      del32[2] = x[j][2]-x[i][2];
-      rsq = del32[0]*del32[0] + del32[1]*del32[1] + del32[2]*del32[2];
-      r32 = sqrt(rsq);
-      del23[0] = -del32[0];
-      del23[1] = -del32[1];
-      del23[2] = -del32[2];
-      r23 = r32;
-      w23 = Sp(r23,rcmin[itype][jtype],rcmax[itype][jtype],dw23);
+    dN3[0] = dN3piRC[0];
+    dN3[1] = dN3piRC[1];
+    dN3[2] = dN3piRC[2];
 
-      for (kk = 0; kk < REBO_numneigh[i]; kk++) {
-        k = REBO_neighs_i[kk];
-        ktype = map[type[k]];
-        if (k == j) continue;
-        del21[0] = x[i][0]-x[k][0];
-        del21[1] = x[i][1]-x[k][1];
-        del21[2] = x[i][2]-x[k][2];
-        rsq = del21[0]*del21[0] + del21[1]*del21[1] + del21[2]*del21[2];
-        r21 = sqrt(rsq);
-        cos321 = - ((del21[0]*del32[0]) + (del21[1]*del32[1]) +
-                    (del21[2]*del32[2])) / (r21*r32);
-        cos321 = MIN(cos321,1.0);
-        cos321 = MAX(cos321,-1.0);
-        sin321 = sqrt(1.0 - cos321*cos321);
-        if (sin321 < TOL) continue;
+    REBO_neighs_i = REBO_firstneigh[i];
+    for (k = 0; k < REBO_numneigh[i]; k++) {
+      atomk = REBO_neighs_i[k];
+      if (atomk != atomj) {
+        ktype = map[type[atomk]];
+        rik[0] = x[atomi][0]-x[atomk][0];
+        rik[1] = x[atomi][1]-x[atomk][1];
+        rik[2] = x[atomi][2]-x[atomk][2];
+        rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+        wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+        Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+          (wik*kronecker(itype,1));
+        SpN = Sp(Nki,Nmin,Nmax,dNki);
 
-        deljk[0] = del21[0]-del23[0];
-        deljk[1] = del21[1]-del23[1];
-        deljk[2] = del21[2]-del23[2];
-        rjk2 = deljk[0]*deljk[0] + deljk[1]*deljk[1] + deljk[2]*deljk[2];
-        rjk=sqrt(rjk2);
-        rik2 = r21*r21;
-        w21 = Sp(r21,rcmin[itype][ktype],rcmax[itype][ktype],dw21);
+        tmp2 = VA*dN3[0]*dwik/rikmag;
+        f[atomi][0] -= tmp2*rik[0];
+        f[atomi][1] -= tmp2*rik[1];
+        f[atomi][2] -= tmp2*rik[2];
+        f[atomk][0] += tmp2*rik[0];
+        f[atomk][1] += tmp2*rik[1];
+        f[atomk][2] += tmp2*rik[2];
 
-        rij = r32;
-        rik = r21;
-        rij2 = r32*r32;
-        rik2 = r21*r21;
-        costmp = 0.5*(rij2+rik2-rjk2)/rij/rik;
-        tspjik = Sp2(costmp,thmin,thmax,dtsjik);
-        dtsjik = -dtsjik;
+        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-        REBO_neighs_j = REBO_firstneigh[j];
-        for (ll = 0; ll < REBO_numneigh[j]; ll++) {
-          l = REBO_neighs_j[ll];
-          ltype = map[type[l]];
-          if (l == i || l == k) continue;
-          del34[0] = x[j][0]-x[l][0];
-          del34[1] = x[j][1]-x[l][1];
-          del34[2] = x[j][2]-x[l][2];
-          rsq = del34[0]*del34[0] + del34[1]*del34[1] + del34[2]*del34[2];
-          r34 = sqrt(rsq);
-          cos234 = (del32[0]*del34[0] + del32[1]*del34[1] +
-                    del32[2]*del34[2]) / (r32*r34);
-          cos234 = MIN(cos234,1.0);
-          cos234 = MAX(cos234,-1.0);
-          sin234 = sqrt(1.0 - cos234*cos234);
-          if (sin234 < TOL) continue;
-          w34 = Sp(r34,rcmin[jtype][ltype],rcmax[jtype][ltype],dw34);
-          delil[0] = del23[0] + del34[0];
-          delil[1] = del23[1] + del34[1];
-          delil[2] = del23[2] + del34[2];
-          ril2 = delil[0]*delil[0] + delil[1]*delil[1] + delil[2]*delil[2];
-          ril=sqrt(ril2);
-          rjl2 = r34*r34;
+        tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)/rikmag;
+        f[atomi][0] -= tmp2*rik[0];
+        f[atomi][1] -= tmp2*rik[1];
+        f[atomi][2] -= tmp2*rik[2];
+        f[atomk][0] += tmp2*rik[0];
+        f[atomk][1] += tmp2*rik[1];
+        f[atomk][2] += tmp2*rik[2];
 
-          rjl = r34;
-          rjl2 = r34*r34;
-          costmp = 0.5*(rij2+rjl2-ril2)/rij/rjl;
-          tspijl = Sp2(costmp,thmin,thmax,dtsijl);
-          dtsijl = -dtsijl; //need minus sign
-          cross321[0] = (del32[1]*del21[2])-(del32[2]*del21[1]);
-          cross321[1] = (del32[2]*del21[0])-(del32[0]*del21[2]);
-          cross321[2] = (del32[0]*del21[1])-(del32[1]*del21[0]);
-          cross321mag = sqrt(cross321[0]*cross321[0]+
-                             cross321[1]*cross321[1]+
-                             cross321[2]*cross321[2]);
-          cross234[0] = (del23[1]*del34[2])-(del23[2]*del34[1]);
-          cross234[1] = (del23[2]*del34[0])-(del23[0]*del34[2]);
-          cross234[2] = (del23[0]*del34[1])-(del23[1]*del34[0]);
-          cross234mag = sqrt(cross234[0]*cross234[0]+
-                             cross234[1]*cross234[1]+
-                             cross234[2]*cross234[2]);
-          cwnum = (cross321[0]*cross234[0]) +
-            (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
-          cwnom = r21*r34*r32*r32*sin321*sin234;
-          cw = cwnum/cwnom;
+        if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-          cw2 = (.5*(1.0-cw));
-          ekijl = epsilonT[ktype][ltype];
-          Ec = 256.0*ekijl/405.0;
-          Vtors = (Ec*(powint(cw2,5)))-(ekijl/10.0);
+        if (fabs(dNki) > TOL) {
+          REBO_neighs_k = REBO_firstneigh[atomk];
+          for (n = 0; n < REBO_numneigh[atomk]; n++) {
+            atomn = REBO_neighs_k[n];
+            if (atomn != atomi) {
+              ntype = map[type[atomn]];
+              rkn[0] = x[atomk][0]-x[atomn][0];
+              rkn[1] = x[atomk][1]-x[atomn][1];
+              rkn[2] = x[atomk][2]-x[atomn][2];
+              rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
+              Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
 
-          if (eflag) *pv2 += evdwl = Vtors*w21*w23*w34*(1.0-tspjik)*(1.0-tspijl);
+              tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)/rknmag;
+              f[atomk][0] -= tmp2*rkn[0];
+              f[atomk][1] -= tmp2*rkn[1];
+              f[atomk][2] -= tmp2*rkn[2];
+              f[atomn][0] += tmp2*rkn[0];
+              f[atomn][1] += tmp2*rkn[1];
+              f[atomn][2] += tmp2*rkn[2];
 
-          dndij[0] = (cross234[1]*del21[2])-(cross234[2]*del21[1]);
-          dndij[1] = (cross234[2]*del21[0])-(cross234[0]*del21[2]);
-          dndij[2] = (cross234[0]*del21[1])-(cross234[1]*del21[0]);
+              if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
+            }
+          }
+        }
+      }
+    }
 
-          tmpvec[0] = (del34[1]*cross321[2])-(del34[2]*cross321[1]);
-          tmpvec[1] = (del34[2]*cross321[0])-(del34[0]*cross321[2]);
-          tmpvec[2] = (del34[0]*cross321[1])-(del34[1]*cross321[0]);
+    // piRC forces to J side
 
-          dndij[0] = dndij[0]+tmpvec[0];
-          dndij[1] = dndij[1]+tmpvec[1];
-          dndij[2] = dndij[2]+tmpvec[2];
+    REBO_neighs = REBO_firstneigh[j];
+    for (l = 0; l < REBO_numneigh[j]; l++) {
+      atoml = REBO_neighs[l];
+      if (atoml != atomi) {
+        ltype = map[type[atoml]];
+        rjl[0] = x[atomj][0]-x[atoml][0];
+        rjl[1] = x[atomj][1]-x[atoml][1];
+        rjl[2] = x[atomj][2]-x[atoml][2];
+        rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+        wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+        Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+          (wjl*kronecker(jtype,1));
+        SpN = Sp(Nlj,Nmin,Nmax,dNlj);
 
-          dndik[0] = (del23[1]*cross234[2])-(del23[2]*cross234[1]);
-          dndik[1] = (del23[2]*cross234[0])-(del23[0]*cross234[2]);
-          dndik[2] = (del23[0]*cross234[1])-(del23[1]*cross234[0]);
+        tmp2 = VA*dN3[1]*dwjl/rjlmag;
+        f[atomj][0] -= tmp2*rjl[0];
+        f[atomj][1] -= tmp2*rjl[1];
+        f[atomj][2] -= tmp2*rjl[2];
+        f[atoml][0] += tmp2*rjl[0];
+        f[atoml][1] += tmp2*rjl[1];
+        f[atoml][2] += tmp2*rjl[2];
 
-          dndjl[0] = (cross321[1]*del23[2])-(cross321[2]*del23[1]);
-          dndjl[1] = (cross321[2]*del23[0])-(cross321[0]*del23[2]);
-          dndjl[2] = (cross321[0]*del23[1])-(cross321[1]*del23[0]);
+        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+
+        tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)/rjlmag;
+        f[atomj][0] -= tmp2*rjl[0];
+        f[atomj][1] -= tmp2*rjl[1];
+        f[atomj][2] -= tmp2*rjl[2];
+        f[atoml][0] += tmp2*rjl[0];
+        f[atoml][1] += tmp2*rjl[1];
+        f[atoml][2] += tmp2*rjl[2];
+
+        if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
+
+        if (fabs(dNlj) > TOL) {
+          REBO_neighs_l = REBO_firstneigh[atoml];
+          for (n = 0; n < REBO_numneigh[atoml]; n++) {
+            atomn = REBO_neighs_l[n];
+            if (atomn != atomj) {
+              ntype = map[type[atomn]];
+              rln[0] = x[atoml][0]-x[atomn][0];
+              rln[1] = x[atoml][1]-x[atomn][1];
+              rln[2] = x[atoml][2]-x[atomn][2];
+              rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
+              Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
 
-          dcidij = ((r23*r23)-(r21*r21)+(rjk*rjk))/(2.0*r23*r23*r21);
-          dcidik = ((r21*r21)-(r23*r23)+(rjk*rjk))/(2.0*r23*r21*r21);
-          dcidjk = (-rjk)/(r23*r21);
-          dcjdji = ((r23*r23)-(r34*r34)+(ril*ril))/(2.0*r23*r23*r34);
-          dcjdjl = ((r34*r34)-(r23*r23)+(ril*ril))/(2.0*r23*r34*r34);
-          dcjdil = (-ril)/(r23*r34);
+              tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)/rlnmag;
+              f[atoml][0] -= tmp2*rln[0];
+              f[atoml][1] -= tmp2*rln[1];
+              f[atoml][2] -= tmp2*rln[2];
+              f[atomn][0] += tmp2*rln[0];
+              f[atomn][1] += tmp2*rln[1];
+              f[atomn][2] += tmp2*rln[2];
 
-          dsidij = (-cos321/sin321)*dcidij;
-          dsidik = (-cos321/sin321)*dcidik;
-          dsidjk = (-cos321/sin321)*dcidjk;
+              if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
+            }
+          }
+        }
+      }
+    }
 
-          dsjdji = (-cos234/sin234)*dcjdji;
-          dsjdjl = (-cos234/sin234)*dcjdjl;
-          dsjdil = (-cos234/sin234)*dcjdil;
+    if (fabs(Tij) > TOL) {
+      dN3[0] = dN3Tij[0];
+      dN3[1] = dN3Tij[1];
+      dN3[2] = dN3Tij[2];
+      atom2 = atomi;
+      atom3 = atomj;
+      r32[0] = -rij[0];
+      r32[1] = -rij[1];
+      r32[2] = -rij[2];
+      r23[0] = rij[0];
+      r23[1] = rij[1];
+      r23[2] = rij[2];
+      r32mag = rijmag;
+      r23mag = rijmag;
 
-          dxidij = (r21*sin321)+(r23*r21*dsidij);
-          dxidik = (r23*sin321)+(r23*r21*dsidik);
-          dxidjk = (r23*r21*dsidjk);
+      REBO_neighs_i = REBO_firstneigh[i];
+      for (k = 0; k < REBO_numneigh[i]; k++) {
+        atomk = REBO_neighs_i[k];
+        atom1 = atomk;
+        ktype = map[type[atomk]];
+        if (atomk != atomj) {
+          r21[0] = x[atom2][0]-x[atom1][0];
+          r21[1] = x[atom2][1]-x[atom1][1];
+          r21[2] = x[atom2][2]-x[atom1][2];
+          r21mag = sqrt(r21[0]*r21[0] + r21[1]*r21[1] + r21[2]*r21[2]);
+          cos321 = ((r21[0]*rij[0])+(r21[1]*rij[1])+(r21[2]*rij[2])) /
+            (r21mag*rijmag);
+          cos321 = MIN(cos321,1.0);
+          cos321 = MAX(cos321,-1.0);
+          sin321 = sqrt(1.0 - cos321*cos321);
 
-          dxjdji = (r34*sin234)+(r23*r34*dsjdji);
-          dxjdjl = (r23*sin234)+(r23*r34*dsjdjl);
-          dxjdil = (r23*r34*dsjdil);
+          if ((sin321 > TOL) && (r21mag > TOL)) { // XXX was sin321 != 0.0
+            sink2i = 1.0/(sin321*sin321);
+            rik2i = 1.0/(r21mag*r21mag);
+            rr = (rijmag*rijmag)-(r21mag*r21mag);
+            rjk[0] = r21[0]-rij[0];
+            rjk[1] = r21[1]-rij[1];
+            rjk[2] = r21[2]-rij[2];
+            rjk2 = (rjk[0]*rjk[0])+(rjk[1]*rjk[1])+(rjk[2]*rjk[2]);
+            rijrik = 2.0*rijmag*r21mag;
+            rik2 = r21mag*r21mag;
+            dctik = (-rr+rjk2)/(rijrik*rik2);
+            dctjk = -2.0/rijrik;
+            w21 = Sp(r21mag,rcmin[itype][ktype],rcmaxp[itype][ktype],dw21);
+            rikmag = r21mag;
+            rij2 = r32mag*r32mag;
+            rik2 = r21mag*r21mag;
+            costmp = 0.5*(rij2+rik2-rjk2)/rijmag/rikmag;
+            tspjik = Sp2(costmp,thmin,thmax,dtsjik);
+            dtsjik = -dtsjik;
 
-          ddndij = (dxidij*cross234mag)+(cross321mag*dxjdji);
-          ddndik = dxidik*cross234mag;
-          ddndjk = dxidjk*cross234mag;
-          ddndjl = cross321mag*dxjdjl;
-          ddndil = cross321mag*dxjdil;
-          dcwddn = -cwnum/(cwnom*cwnom);
-          dcwdn = 1.0/cwnom;
-          dvpdcw = (-1.0)*Ec*(-.5)*5.0*powint(cw2,4) *
-            w23*w21*w34*(1.0-tspjik)*(1.0-tspijl);
+            REBO_neighs_j = REBO_firstneigh[j];
+            for (l = 0; l < REBO_numneigh[j]; l++) {
+              atoml = REBO_neighs_j[l];
+              atom4 = atoml;
+              ltype = map[type[atoml]];
+              if (!(atoml == atomi || atoml == atomk)) {
+                r34[0] = x[atom3][0]-x[atom4][0];
+                r34[1] = x[atom3][1]-x[atom4][1];
+                r34[2] = x[atom3][2]-x[atom4][2];
+                r34mag = sqrt(r34[0]*r34[0] + r34[1]*r34[1] + r34[2]*r34[2]);
+                cos234 = -1.0*((rij[0]*r34[0])+(rij[1]*r34[1]) +
+                               (rij[2]*r34[2]))/(rijmag*r34mag);
+                cos234 = MIN(cos234,1.0);
+                cos234 = MAX(cos234,-1.0);
+                sin234 = sqrt(1.0 - cos234*cos234);
 
-          Ftmp[0] = dvpdcw*((dcwdn*dndij[0])+(dcwddn*ddndij*del23[0]/r23));
-          Ftmp[1] = dvpdcw*((dcwdn*dndij[1])+(dcwddn*ddndij*del23[1]/r23));
-          Ftmp[2] = dvpdcw*((dcwdn*dndij[2])+(dcwddn*ddndij*del23[2]/r23));
-          fi[0] = Ftmp[0];
-          fi[1] = Ftmp[1];
-          fi[2] = Ftmp[2];
-          fj[0] = -Ftmp[0];
-          fj[1] = -Ftmp[1];
-          fj[2] = -Ftmp[2];
+                if ((sin234 > TOL) && (r34mag > TOL)) { // XXX was sin234 != 0.0
+                  sinl2i = 1.0/(sin234*sin234);
+                  rjl2i = 1.0/(r34mag*r34mag);
+                  w34 = Sp(r34mag,rcmin[jtype][ltype],
+                           rcmaxp[jtype][ltype],dw34);
+                  rr = (r23mag*r23mag)-(r34mag*r34mag);
+                  ril[0] = r23[0]+r34[0];
+                  ril[1] = r23[1]+r34[1];
+                  ril[2] = r23[2]+r34[2];
+                  ril2 = (ril[0]*ril[0])+(ril[1]*ril[1])+(ril[2]*ril[2]);
+                  rijrjl = 2.0*r23mag*r34mag;
+                  rjl2 = r34mag*r34mag;
+                  dctjl = (-rr+ril2)/(rijrjl*rjl2);
+                  dctil = -2.0/rijrjl;
+                  rjlmag = r34mag;
+                  rjl2 = r34mag*r34mag;
+                  costmp = 0.5*(rij2+rjl2-ril2)/rijmag/rjlmag;
+                  tspijl = Sp2(costmp,thmin,thmax,dtsijl);
+                  dtsijl = -dtsijl; //need minus sign
+                  prefactor = VA*Tij;
 
-          Ftmp[0] = dvpdcw*((dcwdn*dndik[0])+(dcwddn*ddndik*del21[0]/r21));
-          Ftmp[1] = dvpdcw*((dcwdn*dndik[1])+(dcwddn*ddndik*del21[1]/r21));
-          Ftmp[2] = dvpdcw*((dcwdn*dndik[2])+(dcwddn*ddndik*del21[2]/r21));
-          fi[0] += Ftmp[0];
-          fi[1] += Ftmp[1];
-          fi[2] += Ftmp[2];
-          fk[0] = -Ftmp[0];
-          fk[1] = -Ftmp[1];
-          fk[2] = -Ftmp[2];
+                  cross321[0] = (r32[1]*r21[2])-(r32[2]*r21[1]);
+                  cross321[1] = (r32[2]*r21[0])-(r32[0]*r21[2]);
+                  cross321[2] = (r32[0]*r21[1])-(r32[1]*r21[0]);
+                  cross234[0] = (r23[1]*r34[2])-(r23[2]*r34[1]);
+                  cross234[1] = (r23[2]*r34[0])-(r23[0]*r34[2]);
+                  cross234[2] = (r23[0]*r34[1])-(r23[1]*r34[0]);
 
-          Ftmp[0] = (dvpdcw*dcwddn*ddndjk*deljk[0])/rjk;
-          Ftmp[1] = (dvpdcw*dcwddn*ddndjk*deljk[1])/rjk;
-          Ftmp[2] = (dvpdcw*dcwddn*ddndjk*deljk[2])/rjk;
-          fj[0] += Ftmp[0];
-          fj[1] += Ftmp[1];
-          fj[2] += Ftmp[2];
-          fk[0] -= Ftmp[0];
-          fk[1] -= Ftmp[1];
-          fk[2] -= Ftmp[2];
+                  cwnum = (cross321[0]*cross234[0]) +
+                    (cross321[1]*cross234[1])+(cross321[2]*cross234[2]);
+                  cwnom = r21mag*r34mag*r23mag*r23mag*sin321*sin234;
+                  om1234 = cwnum/cwnom;
+                  cw = om1234;
 
-          Ftmp[0] = dvpdcw*((dcwdn*dndjl[0])+(dcwddn*ddndjl*del34[0]/r34));
-          Ftmp[1] = dvpdcw*((dcwdn*dndjl[1])+(dcwddn*ddndjl*del34[1]/r34));
-          Ftmp[2] = dvpdcw*((dcwdn*dndjl[2])+(dcwddn*ddndjl*del34[2]/r34));
-          fj[0] += Ftmp[0];
-          fj[1] += Ftmp[1];
-          fj[2] += Ftmp[2];
-          fl[0] = -Ftmp[0];
-          fl[1] = -Ftmp[1];
-          fl[2] = -Ftmp[2];
+                  dt1dik = (rik2i)-(dctik*sink2i*cos321);
+                  dt1djk = (-dctjk*sink2i*cos321);
+                  dt1djl = (rjl2i)-(dctjl*sinl2i*cos234);
+                  dt1dil = (-dctil*sinl2i*cos234);
 
-          Ftmp[0] = (dvpdcw*dcwddn*ddndil*delil[0])/ril;
-          Ftmp[1] = (dvpdcw*dcwddn*ddndil*delil[1])/ril;
-          Ftmp[2] = (dvpdcw*dcwddn*ddndil*delil[2])/ril;
-          fi[0] += Ftmp[0];
-          fi[1] += Ftmp[1];
-          fi[2] += Ftmp[2];
-          fl[0] -= Ftmp[0];
-          fl[1] -= Ftmp[1];
-          fl[2] -= Ftmp[2];
+                  dt2dik[0] = (-r23[2]*cross234[1])+(r23[1]*cross234[2]);
+                  dt2dik[1] = (-r23[0]*cross234[2])+(r23[2]*cross234[0]);
+                  dt2dik[2] = (-r23[1]*cross234[0])+(r23[0]*cross234[1]);
 
-          // coordination forces
+                  dt2djl[0] = (-r23[1]*cross321[2])+(r23[2]*cross321[1]);
+                  dt2djl[1] = (-r23[2]*cross321[0])+(r23[0]*cross321[2]);
+                  dt2djl[2] = (-r23[0]*cross321[1])+(r23[1]*cross321[0]);
 
-          fpair = Vtors*dw21*w23*w34*(1.0-tspjik)*(1.0-tspijl) / r21;
-          fi[0] -= del21[0]*fpair;
-          fi[1] -= del21[1]*fpair;
-          fi[2] -= del21[2]*fpair;
-          fk[0] += del21[0]*fpair;
-          fk[1] += del21[1]*fpair;
-          fk[2] += del21[2]*fpair;
+                  aa = (prefactor*2.0*cw/cwnom)*w21*w34 *
+                    (1.0-tspjik)*(1.0-tspijl);
+                  aaa1 = -prefactor*(1.0-square(om1234)) *
+                    (1.0-tspjik)*(1.0-tspijl);
+                  aaa2 = aaa1*w21*w34;
+                  at2 = aa*cwnum;
 
-          fpair = Vtors*w21*dw23*w34*(1.0-tspjik)*(1.0-tspijl) / r23;
-          fi[0] -= del23[0]*fpair;
-          fi[1] -= del23[1]*fpair;
-          fi[2] -= del23[2]*fpair;
-          fj[0] += del23[0]*fpair;
-          fj[1] += del23[1]*fpair;
-          fj[2] += del23[2]*fpair;
+                  fcikpc = (-dt1dik*at2)+(aaa2*dtsjik*dctik*(1.0-tspijl));
+                  fcjlpc = (-dt1djl*at2)+(aaa2*dtsijl*dctjl*(1.0-tspjik));
+                  fcjkpc = (-dt1djk*at2)+(aaa2*dtsjik*dctjk*(1.0-tspijl));
+                  fcilpc = (-dt1dil*at2)+(aaa2*dtsijl*dctil*(1.0-tspjik));
 
-          fpair = Vtors*w21*w23*dw34*(1.0-tspjik)*(1.0-tspijl) / r34;
-          fj[0] -= del34[0]*fpair;
-          fj[1] -= del34[1]*fpair;
-          fj[2] -= del34[2]*fpair;
-          fl[0] += del34[0]*fpair;
-          fl[1] += del34[1]*fpair;
-          fl[2] += del34[2]*fpair;
+                  F12[0] = (fcikpc*r21[0])+(aa*dt2dik[0]);
+                  F12[1] = (fcikpc*r21[1])+(aa*dt2dik[1]);
+                  F12[2] = (fcikpc*r21[2])+(aa*dt2dik[2]);
 
-          // additional cut off function forces
+                  F34[0] = (fcjlpc*r34[0])+(aa*dt2djl[0]);
+                  F34[1] = (fcjlpc*r34[1])+(aa*dt2djl[1]);
+                  F34[2] = (fcjlpc*r34[2])+(aa*dt2djl[2]);
 
-          fcpc = -Vtors*w21*w23*w34*dtsjik*(1.0-tspijl);
-          fpair = fcpc*dcidij/rij;
-          fi[0] += fpair*del23[0];
-          fi[1] += fpair*del23[1];
-          fi[2] += fpair*del23[2];
-          fj[0] -= fpair*del23[0];
-          fj[1] -= fpair*del23[1];
-          fj[2] -= fpair*del23[2];
+                  F31[0] = (fcjkpc*rjk[0]);
+                  F31[1] = (fcjkpc*rjk[1]);
+                  F31[2] = (fcjkpc*rjk[2]);
 
-          fpair = fcpc*dcidik/rik;
-          fi[0] += fpair*del21[0];
-          fi[1] += fpair*del21[1];
-          fi[2] += fpair*del21[2];
-          fk[0] -= fpair*del21[0];
-          fk[1] -= fpair*del21[1];
-          fk[2] -= fpair*del21[2];
+                  F24[0] = (fcilpc*ril[0]);
+                  F24[1] = (fcilpc*ril[1]);
+                  F24[2] = (fcilpc*ril[2]);
 
-          fpair = fcpc*dcidjk/rjk;
-          fj[0] += fpair*deljk[0];
-          fj[1] += fpair*deljk[1];
-          fj[2] += fpair*deljk[2];
-          fk[0] -= fpair*deljk[0];
-          fk[1] -= fpair*deljk[1];
-          fk[2] -= fpair*deljk[2];
+                  f1[0] = -F12[0]-F31[0];
+                  f1[1] = -F12[1]-F31[1];
+                  f1[2] = -F12[2]-F31[2];
+                  f2[0] = F12[0]+F31[0];
+                  f2[1] = F12[1]+F31[1];
+                  f2[2] = F12[2]+F31[2];
+                  f3[0] = F34[0]+F24[0];
+                  f3[1] = F34[1]+F24[1];
+                  f3[2] = F34[2]+F24[2];
+                  f4[0] = -F34[0]-F24[0];
+                  f4[1] = -F34[1]-F24[1];
+                  f4[2] = -F34[2]-F24[2];
 
-          fcpc = -Vtors*w21*w23*w34*(1.0-tspjik)*dtsijl;
-          fpair = fcpc*dcjdji/rij;
-          fi[0] += fpair*del23[0];
-          fi[1] += fpair*del23[1];
-          fi[2] += fpair*del23[2];
-          fj[0] -= fpair*del23[0];
-          fj[1] -= fpair*del23[1];
-          fj[2] -= fpair*del23[2];
+                  rijmbr = rcmin[itype][jtype] / realrijmag;
+                  f2[0] += rijmbr * (F24[0] - (realrij[0] * realrij[0] * F24[0] + realrij[0] * realrij[1] * F24[1] + realrij[0] * realrij[2] * F24[2]) / (realrijmag * realrijmag));
+                  f2[1] += rijmbr * (F24[1] - (realrij[1] * realrij[0] * F24[0] + realrij[1] * realrij[1] * F24[1] + realrij[1] * realrij[2] * F24[2]) / (realrijmag * realrijmag));
+                  f2[2] += rijmbr * (F24[2] - (realrij[2] * realrij[0] * F24[0] + realrij[2] * realrij[1] * F24[1] + realrij[2] * realrij[2] * F24[2]) / (realrijmag * realrijmag));
+                  f3[0] -= rijmbr * (F24[0] - (realrij[0] * realrij[0] * F24[0] + realrij[0] * realrij[1] * F24[1] + realrij[0] * realrij[2] * F24[2]) / (realrijmag * realrijmag));
+                  f3[1] -= rijmbr * (F24[1] - (realrij[1] * realrij[0] * F24[0] + realrij[1] * realrij[1] * F24[1] + realrij[1] * realrij[2] * F24[2]) / (realrijmag * realrijmag));
+                  f3[2] -= rijmbr * (F24[2] - (realrij[2] * realrij[0] * F24[0] + realrij[2] * realrij[1] * F24[1] + realrij[2] * realrij[2] * F24[2]) / (realrijmag * realrijmag));
+
+                  f2[0] -= rijmbr * (F31[0] - (realrij[0] * realrij[0] * F31[0] + realrij[0] * realrij[1] * F31[1] + realrij[0] * realrij[2] * F31[2]) / (realrijmag * realrijmag));
+                  f2[1] -= rijmbr * (F31[1] - (realrij[1] * realrij[0] * F31[0] + realrij[1] * realrij[1] * F31[1] + realrij[1] * realrij[2] * F31[2]) / (realrijmag * realrijmag));
+                  f2[2] -= rijmbr * (F31[2] - (realrij[2] * realrij[0] * F31[0] + realrij[2] * realrij[1] * F31[1] + realrij[2] * realrij[2] * F31[2]) / (realrijmag * realrijmag));
+                  f3[0] += rijmbr * (F31[0] - (realrij[0] * realrij[0] * F31[0] + realrij[0] * realrij[1] * F31[1] + realrij[0] * realrij[2] * F31[2]) / (realrijmag * realrijmag));
+                  f3[1] += rijmbr * (F31[1] - (realrij[1] * realrij[0] * F31[0] + realrij[1] * realrij[1] * F31[1] + realrij[1] * realrij[2] * F31[2]) / (realrijmag * realrijmag));
+                  f3[2] += rijmbr * (F31[2] - (realrij[2] * realrij[0] * F31[0] + realrij[2] * realrij[1] * F31[1] + realrij[2] * realrij[2] * F31[2]) / (realrijmag * realrijmag));
 
-          fpair = fcpc*dcjdjl/rjl;
-          fj[0] += fpair*del34[0];
-          fj[1] += fpair*del34[1];
-          fj[2] += fpair*del34[2];
-          fl[0] -= fpair*del34[0];
-          fl[1] -= fpair*del34[1];
-          fl[2] -= fpair*del34[2];
+                  // coordination forces
 
-          fpair = fcpc*dcjdil/ril;
-          fi[0] += fpair*delil[0];
-          fi[1] += fpair*delil[1];
-          fi[2] += fpair*delil[2];
-          fl[0] -= fpair*delil[0];
-          fl[1] -= fpair*delil[1];
-          fl[2] -= fpair*delil[2];
+                  tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+                    (1.0-tspjik)*(1.0-tspijl)*dw21*w34/r21mag;
+                  f2[0] -= tmp2*r21[0];
+                  f2[1] -= tmp2*r21[1];
+                  f2[2] -= tmp2*r21[2];
+                  f1[0] += tmp2*r21[0];
+                  f1[1] += tmp2*r21[1];
+                  f1[2] += tmp2*r21[2];
 
-          // sum per-atom forces into atom force array
+                  tmp2 = VA*Tij*((1.0-(om1234*om1234))) *
+                    (1.0-tspjik)*(1.0-tspijl)*w21*dw34/r34mag;
+                  f3[0] -= tmp2*r34[0];
+                  f3[1] -= tmp2*r34[1];
+                  f3[2] -= tmp2*r34[2];
+                  f4[0] += tmp2*r34[0];
+                  f4[1] += tmp2*r34[1];
+                  f4[2] += tmp2*r34[2];
 
-          f[i][0] += fi[0]; f[i][1] += fi[1]; f[i][2] += fi[2];
-          f[j][0] += fj[0]; f[j][1] += fj[1]; f[j][2] += fj[2];
-          f[k][0] += fk[0]; f[k][1] += fk[1]; f[k][2] += fk[2];
-          f[l][0] += fl[0]; f[l][1] += fl[1]; f[l][2] += fl[2];
+                  f[atom1][0] += f1[0]; f[atom1][1] += f1[1];
+                  f[atom1][2] += f1[2];
+                  f[atom2][0] += f2[0]; f[atom2][1] += f2[1];
+                  f[atom2][2] += f2[2];
+                  f[atom3][0] += f3[0]; f[atom3][1] += f3[1];
+                  f[atom3][2] += f3[2];
+                  f[atom4][0] += f4[0]; f[atom4][1] += f4[1];
+                  f[atom4][2] += f4[2];
 
-          if (evflag) {
-            delkl[0] = delil[0] - del21[0];
-            delkl[1] = delil[1] - del21[1];
-            delkl[2] = delil[2] - del21[2];
-            ev_tally4_thr(this,i,j,k,l,evdwl,fi,fj,fk,delil,del34,delkl,thr);
+                  if (vflag_atom) {
+                    r13[0] = -rjk[0]; r13[1] = -rjk[1]; r13[2] = -rjk[2];
+                    r43[0] = -r34[0]; r43[1] = -r34[1]; r43[2] = -r34[2];
+                    v_tally4_thr(atom1,atom2,atom3,atom4,f1,f2,f4,r13,r23,r43,thr);
+                  }
+                }
+              }
+            }
           }
         }
       }
-    }
-  }
-}
 
-/* ----------------------------------------------------------------------
-   create REBO neighbor list from main neighbor list
-   REBO neighbor list stores neighbors of ghost atoms
-------------------------------------------------------------------------- */
+      REBO_neighs = REBO_firstneigh[i];
+      for (k = 0; k < REBO_numneigh[i]; k++) {
+        atomk = REBO_neighs[k];
+        if (atomk != atomj) {
+          ktype = map[type[atomk]];
+          rik[0] = x[atomi][0]-x[atomk][0];
+          rik[1] = x[atomi][1]-x[atomk][1];
+          rik[2] = x[atomi][2]-x[atomk][2];
+          rikmag = sqrt((rik[0]*rik[0])+(rik[1]*rik[1])+(rik[2]*rik[2]));
+          wik = Sp(rikmag,rcmin[itype][ktype],rcmax[itype][ktype],dwik);
+          Nki = nC[atomk]-(wik*kronecker(itype,0))+nH[atomk] -
+            (wik*kronecker(itype,1));
+          SpN = Sp(Nki,Nmin,Nmax,dNki);
 
-void PairAIREBOOMP::REBO_neigh_thr()
-{
-  const int nthreads = comm->nthreads;
+          tmp2 = VA*dN3[0]*dwik*Etmp/rikmag;
+          f[atomi][0] -= tmp2*rik[0];
+          f[atomi][1] -= tmp2*rik[1];
+          f[atomi][2] -= tmp2*rik[2];
+          f[atomk][0] += tmp2*rik[0];
+          f[atomk][1] += tmp2*rik[1];
+          f[atomk][2] += tmp2*rik[2];
 
-  if (atom->nmax > maxlocal) {
-    maxlocal = atom->nmax;
-    memory->destroy(REBO_numneigh);
-    memory->sfree(REBO_firstneigh);
-    memory->destroy(nC);
-    memory->destroy(nH);
-    memory->create(REBO_numneigh,maxlocal,"AIREBO:numneigh");
-    REBO_firstneigh = (int **) memory->smalloc(maxlocal*sizeof(int *),
-                                               "AIREBO:firstneigh");
-    memory->create(nC,maxlocal,"AIREBO:nC");
-    memory->create(nH,maxlocal,"AIREBO:nH");
-  }
+          if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-#if defined(_OPENMP)
-#pragma omp parallel default(none)
-#endif
-  {
-    int i,j,ii,jj,n,jnum,itype,jtype;
-    double xtmp,ytmp,ztmp,delx,dely,delz,rsq,dS;
-    int *ilist,*jlist,*numneigh,**firstneigh;
-    int *neighptr;
+          tmp2 = VA*dN3[2]*(2.0*NconjtmpI*dwik*SpN)*Etmp/rikmag;
+          f[atomi][0] -= tmp2*rik[0];
+          f[atomi][1] -= tmp2*rik[1];
+          f[atomi][2] -= tmp2*rik[2];
+          f[atomk][0] += tmp2*rik[0];
+          f[atomk][1] += tmp2*rik[1];
+          f[atomk][2] += tmp2*rik[2];
 
-    double **x = atom->x;
-    int *type = atom->type;
+          if (vflag_atom) v_tally2_thr(atomi,atomk,-tmp2,rik,thr);
 
-    const int allnum = list->inum + list->gnum;
-    ilist = list->ilist;
-    numneigh = list->numneigh;
-    firstneigh = list->firstneigh;
+          if (fabs(dNki) > TOL) {
+            REBO_neighs_k = REBO_firstneigh[atomk];
+            for (n = 0; n < REBO_numneigh[atomk]; n++) {
+              atomn = REBO_neighs_k[n];
+              ntype = map[type[atomn]];
+              if (atomn !=atomi) {
+                rkn[0] = x[atomk][0]-x[atomn][0];
+                rkn[1] = x[atomk][1]-x[atomn][1];
+                rkn[2] = x[atomk][2]-x[atomn][2];
+                rknmag = sqrt((rkn[0]*rkn[0])+(rkn[1]*rkn[1])+(rkn[2]*rkn[2]));
+                Sp(rknmag,rcmin[ktype][ntype],rcmax[ktype][ntype],dwkn);
 
-#if defined(_OPENMP)
-    const int tid = omp_get_thread_num();
-#else
-    const int tid = 0;
-#endif
+                tmp2 = VA*dN3[2]*(2.0*NconjtmpI*wik*dNki*dwkn)*Etmp/rknmag;
+                f[atomk][0] -= tmp2*rkn[0];
+                f[atomk][1] -= tmp2*rkn[1];
+                f[atomk][2] -= tmp2*rkn[2];
+                f[atomn][0] += tmp2*rkn[0];
+                f[atomn][1] += tmp2*rkn[1];
+                f[atomn][2] += tmp2*rkn[2];
 
-    const int iidelta = 1 + allnum/nthreads;
-    const int iifrom = tid*iidelta;
-    const int iito = ((iifrom+iidelta)>allnum) ? allnum : (iifrom+iidelta);
+                if (vflag_atom) v_tally2_thr(atomk,atomn,-tmp2,rkn,thr);
+              }
+            }
+          }
+        }
+      }
 
-    // store all REBO neighs of owned and ghost atoms
-    // scan full neighbor list of I
+      // Tij forces
 
-    // each thread has its own page allocator
-    MyPage<int> &ipg = ipage[tid];
-    ipg.reset();
+      REBO_neighs = REBO_firstneigh[j];
+      for (l = 0; l < REBO_numneigh[j]; l++) {
+        atoml = REBO_neighs[l];
+        if (atoml != atomi) {
+          ltype = map[type[atoml]];
+          rjl[0] = x[atomj][0]-x[atoml][0];
+          rjl[1] = x[atomj][1]-x[atoml][1];
+          rjl[2] = x[atomj][2]-x[atoml][2];
+          rjlmag = sqrt((rjl[0]*rjl[0])+(rjl[1]*rjl[1])+(rjl[2]*rjl[2]));
+          wjl = Sp(rjlmag,rcmin[jtype][ltype],rcmax[jtype][ltype],dwjl);
+          Nlj = nC[atoml]-(wjl*kronecker(jtype,0))+nH[atoml] -
+            (wjl*kronecker(jtype,1));
+          SpN = Sp(Nlj,Nmin,Nmax,dNlj);
 
-    for (ii = iifrom; ii < iito; ii++) {
-      i = ilist[ii];
+          tmp2 = VA*dN3[1]*dwjl*Etmp/rjlmag;
+          f[atomj][0] -= tmp2*rjl[0];
+          f[atomj][1] -= tmp2*rjl[1];
+          f[atomj][2] -= tmp2*rjl[2];
+          f[atoml][0] += tmp2*rjl[0];
+          f[atoml][1] += tmp2*rjl[1];
+          f[atoml][2] += tmp2*rjl[2];
 
-      n = 0;
-      neighptr = ipg.vget();
+          if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
 
-      xtmp = x[i][0];
-      ytmp = x[i][1];
-      ztmp = x[i][2];
-      itype = map[type[i]];
-      nC[i] = nH[i] = 0.0;
-      jlist = firstneigh[i];
-      jnum = numneigh[i];
+          tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*dwjl*SpN)*Etmp/rjlmag;
+          f[atomj][0] -= tmp2*rjl[0];
+          f[atomj][1] -= tmp2*rjl[1];
+          f[atomj][2] -= tmp2*rjl[2];
+          f[atoml][0] += tmp2*rjl[0];
+          f[atoml][1] += tmp2*rjl[1];
+          f[atoml][2] += tmp2*rjl[2];
 
-      for (jj = 0; jj < jnum; jj++) {
-        j = jlist[jj];
-        j &= NEIGHMASK;
-        jtype = map[type[j]];
-        delx = xtmp - x[j][0];
-        dely = ytmp - x[j][1];
-        delz = ztmp - x[j][2];
-        rsq = delx*delx + dely*dely + delz*delz;
+          if (vflag_atom) v_tally2_thr(atomj,atoml,-tmp2,rjl,thr);
 
-        if (rsq < rcmaxsq[itype][jtype]) {
-          neighptr[n++] = j;
-          if (jtype == 0)
-            nC[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
-          else
-            nH[i] += Sp(sqrt(rsq),rcmin[itype][jtype],rcmax[itype][jtype],dS);
+          if (fabs(dNlj) > TOL) {
+            REBO_neighs_l = REBO_firstneigh[atoml];
+            for (n = 0; n < REBO_numneigh[atoml]; n++) {
+              atomn = REBO_neighs_l[n];
+              ntype = map[type[atomn]];
+              if (atomn != atomj) {
+                rln[0] = x[atoml][0]-x[atomn][0];
+                rln[1] = x[atoml][1]-x[atomn][1];
+                rln[2] = x[atoml][2]-x[atomn][2];
+                rlnmag = sqrt((rln[0]*rln[0])+(rln[1]*rln[1])+(rln[2]*rln[2]));
+                Sp(rlnmag,rcmin[ltype][ntype],rcmax[ltype][ntype],dwln);
+
+                tmp2 = VA*dN3[2]*(2.0*NconjtmpJ*wjl*dNlj*dwln)*Etmp/rlnmag;
+                f[atoml][0] -= tmp2*rln[0];
+                f[atoml][1] -= tmp2*rln[1];
+                f[atoml][2] -= tmp2*rln[2];
+                f[atomn][0] += tmp2*rln[0];
+                f[atomn][1] += tmp2*rln[1];
+                f[atomn][2] += tmp2*rln[2];
+
+                if (vflag_atom) v_tally2_thr(atoml,atomn,-tmp2,rln,thr);
+              }
+            }
+          }
         }
       }
-
-      REBO_firstneigh[i] = neighptr;
-      REBO_numneigh[i] = n;
-      ipg.vgot(n);
-      if (ipg.status())
-        error->one(FLERR,"REBO list overflow, boost neigh_modify one");
     }
   }
-}
 
+  return Stb;
+}
 
 /* ---------------------------------------------------------------------- */