From 3fb19bcea66476b161bb8c7f21189d5e4746ef4e Mon Sep 17 00:00:00 2001
From: sjplimp <sjplimp@f3b2605a-c512-4ea7-a41b-209d697bcdaa>
Date: Thu, 1 Mar 2012 16:48:08 +0000
Subject: [PATCH] git-svn-id: svn://svn.icms.temple.edu/lammps-ro/trunk@7873
 f3b2605a-c512-4ea7-a41b-209d697bcdaa

---
 src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp    | 338 +++++++++---------
 src/Makefile                                  |   7 +
 src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp   | 206 +++++------
 src/OPT/pair_lj_cut_coul_long_tip4p_opt.h     |   2 +-
 .../pair_lj_cut_coul_long_tip4p_omp.cpp       | 159 ++++----
 .../pair_lj_cut_coul_long_tip4p_omp.h         |   2 +-
 .../pair_lj_cut_coul_pppm_tip4p_omp.cpp       | 163 +++++----
 .../pair_lj_cut_coul_pppm_tip4p_omp.h         |   4 +-
 8 files changed, 453 insertions(+), 428 deletions(-)

diff --git a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp
index d9cac1e9e0..f1271f3456 100644
--- a/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp
+++ b/src/KSPACE/pair_lj_cut_coul_long_tip4p.cpp
@@ -90,6 +90,7 @@ void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag)
   double *special_lj = force->special_lj;
   int newton_pair = force->newton_pair;
   double qqrd2e = force->qqrd2e;
+  double cut_coulsqplus = (cut_coul+2.0*qdist) * (cut_coul+2.0*qdist);
 
   inum = list->inum;
   ilist = list->ilist;
@@ -124,7 +125,7 @@ void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag)
       rsq = delx*delx + dely*dely + delz*delz;
       jtype = type[j];
 
-      // LJ interation based on true rsq
+      // LJ interaction based on true rsq
 
       if (rsq < cut_ljsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
@@ -150,209 +151,213 @@ void PairLJCutCoulLongTIP4P::compute(int eflag, int vflag)
       }
 
       // adjust rsq and delxyz for off-site O charge(s) if necessary
+      // but only if they are within reach
+
+      if (rsq < cut_coulsqplus) {
+
+	if (itype == typeO || jtype == typeO) { 
+	  if (jtype == typeO) {
+	    find_M(j,jH1,jH2,xjM);
+	    x2 = xjM;
+	  } else x2 = x[j];
+	  delx = x1[0] - x2[0];
+	  dely = x1[1] - x2[1];
+	  delz = x1[2] - x2[2];
+	  rsq = delx*delx + dely*dely + delz*delz;
+	}
 
-      if (itype == typeO || jtype == typeO) { 
-	if (jtype == typeO) {
-	  find_M(j,jH1,jH2,xjM);
-	  x2 = xjM;
-	} else x2 = x[j];
-	delx = x1[0] - x2[0];
-	dely = x1[1] - x2[1];
-	delz = x1[2] - x2[2];
-	rsq = delx*delx + dely*dely + delz*delz;
-      }
-
-      // Coulombic interaction based on modified rsq
-
-      if (rsq < cut_coulsq) {
-	r2inv = 1 / rsq;
-	if (!ncoultablebits || rsq <= tabinnersq) {
-	  r = sqrt(rsq);
-	  grij = g_ewald * r;
-	  expm2 = exp(-grij*grij);
-	  t = 1.0 / (1.0 + EWALD_P*grij);
-	  erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
-	  prefactor = qqrd2e * qtmp*q[j]/r;
-	  forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
-	  if (factor_coul < 1.0) {
-	    forcecoul -= (1.0-factor_coul)*prefactor; 
+	// Coulombic interaction based on modified rsq
+
+	if (rsq < cut_coulsq) {
+	  r2inv = 1 / rsq;
+	  if (!ncoultablebits || rsq <= tabinnersq) {
+	    r = sqrt(rsq);
+	    grij = g_ewald * r;
+	    expm2 = exp(-grij*grij);
+	    t = 1.0 / (1.0 + EWALD_P*grij);
+	    erfc = t * (A1+t*(A2+t*(A3+t*(A4+t*A5)))) * expm2;
+	    prefactor = qqrd2e * qtmp*q[j]/r;
+	    forcecoul = prefactor * (erfc + EWALD_F*grij*expm2);
+	    if (factor_coul < 1.0) {
+	      forcecoul -= (1.0-factor_coul)*prefactor; 
+	    }
+	  } else {
+	    union_int_float_t rsq_lookup;
+	    rsq_lookup.f = rsq;
+	    itable = rsq_lookup.i & ncoulmask;
+	    itable >>= ncoulshiftbits;
+	    fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
+	    table = ftable[itable] + fraction*dftable[itable];
+	    forcecoul = qtmp*q[j] * table;
+	    if (factor_coul < 1.0) {
+	      table = ctable[itable] + fraction*dctable[itable];
+	      prefactor = qtmp*q[j] * table;
+	      forcecoul -= (1.0-factor_coul)*prefactor;
+	    }
 	  }
-	} else {
-	  union_int_float_t rsq_lookup;
-	  rsq_lookup.f = rsq;
-	  itable = rsq_lookup.i & ncoulmask;
-	  itable >>= ncoulshiftbits;
-	  fraction = (rsq_lookup.f - rtable[itable]) * drtable[itable];
-	  table = ftable[itable] + fraction*dftable[itable];
-	  forcecoul = qtmp*q[j] * table;
-	  if (factor_coul < 1.0) {
-	    table = ctable[itable] + fraction*dctable[itable];
-	    prefactor = qtmp*q[j] * table;
-	    forcecoul -= (1.0-factor_coul)*prefactor;
-	  }
-	}
 	
-	cforce = forcecoul * r2inv;
-
-	// if i,j are not O atoms, force is applied directly
-	// if i or j are O atoms, force is on fictitious atom & partitioned
-	// force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999)
-	// f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f
-	// preserves total force and torque on water molecule
-	// virial = sum(r x F) where each water's atoms are near xi and xj
-	// vlist stores 2,4,6 atoms whose forces contribute to virial
+	  cforce = forcecoul * r2inv;
+
+	  // if i,j are not O atoms, force is applied directly
+	  // if i or j are O atoms, force is on fictitious atom & partitioned
+	  // force partitioning due to Feenstra, J Comp Chem, 20, 786 (1999)
+	  // f_f = fictitious force, fO = f_f (1 - 2 alpha), fH = alpha f_f
+	  // preserves total force and torque on water molecule
+	  // virial = sum(r x F) where each water's atoms are near xi and xj
+	  // vlist stores 2,4,6 atoms whose forces contribute to virial
 	
-	n = 0;
+	  n = 0;
 	
-	if (itype != typeO) {
-	  f[i][0] += delx * cforce;
-	  f[i][1] += dely * cforce;
-	  f[i][2] += delz * cforce;
+	  if (itype != typeO) {
+	    f[i][0] += delx * cforce;
+	    f[i][1] += dely * cforce;
+	    f[i][2] += delz * cforce;
 	  
-	  if (vflag) {
-	    v[0] = x[i][0] * delx * cforce;
-	    v[1] = x[i][1] * dely * cforce;
-	    v[2] = x[i][2] * delz * cforce;
-	    v[3] = x[i][0] * dely * cforce;
-	    v[4] = x[i][0] * delz * cforce;
-	    v[5] = x[i][1] * delz * cforce;
-	    vlist[n++] = i;
-	  }
+	    if (vflag) {
+	      v[0] = x[i][0] * delx * cforce;
+	      v[1] = x[i][1] * dely * cforce;
+	      v[2] = x[i][2] * delz * cforce;
+	      v[3] = x[i][0] * dely * cforce;
+	      v[4] = x[i][0] * delz * cforce;
+	      v[5] = x[i][1] * delz * cforce;
+	      vlist[n++] = i;
+	    }
 	  
-	} else {
+	  } else {
 
-	  fd[0] = delx*cforce;
-	  fd[1] = dely*cforce;
-	  fd[2] = delz*cforce;
+	    fd[0] = delx*cforce;
+	    fd[1] = dely*cforce;
+	    fd[2] = delz*cforce;
 
-	  delxOM = x[i][0] - x1[0];
-	  delyOM = x[i][1] - x1[1];
-	  delzOM = x[i][2] - x1[2];
+	    delxOM = x[i][0] - x1[0];
+	    delyOM = x[i][1] - x1[1];
+	    delzOM = x[i][2] - x1[2];
 
-	  ddotf = (delxOM * fd[0] + delyOM * fd[1] + delzOM * fd[2]) /
-            (qdist*qdist);
+	    ddotf = (delxOM * fd[0] + delyOM * fd[1] + delzOM * fd[2]) /
+	      (qdist*qdist);
 	  
-	  f1[0] = ddotf * delxOM;
-	  f1[1] = ddotf * delyOM;
-	  f1[2] = ddotf * delzOM;
+	    f1[0] = ddotf * delxOM;
+	    f1[1] = ddotf * delyOM;
+	    f1[2] = ddotf * delzOM;
 	  
-	  fO[0] = fd[0] - alpha * (fd[0] - f1[0]);
-	  fO[1] = fd[1] - alpha * (fd[1] - f1[1]);
-	  fO[2] = fd[2] - alpha * (fd[2] - f1[2]);
+	    fO[0] = fd[0] - alpha * (fd[0] - f1[0]);
+	    fO[1] = fd[1] - alpha * (fd[1] - f1[1]);
+	    fO[2] = fd[2] - alpha * (fd[2] - f1[2]);
 	  
-	  fH[0] = 0.5 * alpha * (fd[0] - f1[0]);
-	  fH[1] = 0.5 * alpha * (fd[1] - f1[1]);
-	  fH[2] = 0.5 * alpha * (fd[2] - f1[2]);
+	    fH[0] = 0.5 * alpha * (fd[0] - f1[0]);
+	    fH[1] = 0.5 * alpha * (fd[1] - f1[1]);
+	    fH[2] = 0.5 * alpha * (fd[2] - f1[2]);
 	  
-	  f[i][0] += fO[0];
-	  f[i][1] += fO[1];
-	  f[i][2] += fO[2];
+	    f[i][0] += fO[0];
+	    f[i][1] += fO[1];
+	    f[i][2] += fO[2];
 	  
-	  f[iH1][0] += fH[0];
-	  f[iH1][1] += fH[1];
-	  f[iH1][2] += fH[2];
+	    f[iH1][0] += fH[0];
+	    f[iH1][1] += fH[1];
+	    f[iH1][2] += fH[2];
 	  
-	  f[iH2][0] += fH[0];
-	  f[iH2][1] += fH[1];
-	  f[iH2][2] += fH[2];
+	    f[iH2][0] += fH[0];
+	    f[iH2][1] += fH[1];
+	    f[iH2][2] += fH[2];
 	  
-	  if (vflag) {
-	    domain->closest_image(x[i],x[iH1],xH1);
-	    domain->closest_image(x[i],x[iH2],xH2);
+	    if (vflag) {
+	      domain->closest_image(x[i],x[iH1],xH1);
+	      domain->closest_image(x[i],x[iH2],xH2);
 	    
-	    v[0] = x[i][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0];
-	    v[1] = x[i][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1];
-	    v[2] = x[i][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2];
-	    v[3] = x[i][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1];
-	    v[4] = x[i][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2];
-	    v[5] = x[i][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2];
+	      v[0] = x[i][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0];
+	      v[1] = x[i][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1];
+	      v[2] = x[i][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2];
+	      v[3] = x[i][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1];
+	      v[4] = x[i][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2];
+	      v[5] = x[i][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2];
 	    
-	    vlist[n++] = i;
-	    vlist[n++] = iH1;
-	    vlist[n++] = iH2;
+	      vlist[n++] = i;
+	      vlist[n++] = iH1;
+	      vlist[n++] = iH2;
+	    }
 	  }
-	}
 	
-	if (jtype != typeO) {
-	  f[j][0] -= delx * cforce;
-	  f[j][1] -= dely * cforce;
-	  f[j][2] -= delz * cforce;
+	  if (jtype != typeO) {
+	    f[j][0] -= delx * cforce;
+	    f[j][1] -= dely * cforce;
+	    f[j][2] -= delz * cforce;
 	  
-	  if (vflag) {
-	    v[0] -= x[j][0] * delx * cforce;
-	    v[1] -= x[j][1] * dely * cforce;
-	    v[2] -= x[j][2] * delz * cforce;
-	    v[3] -= x[j][0] * dely * cforce;
-	    v[4] -= x[j][0] * delz * cforce;
-	    v[5] -= x[j][1] * delz * cforce;
-	    vlist[n++] = j;
-	  }
+	    if (vflag) {
+	      v[0] -= x[j][0] * delx * cforce;
+	      v[1] -= x[j][1] * dely * cforce;
+	      v[2] -= x[j][2] * delz * cforce;
+	      v[3] -= x[j][0] * dely * cforce;
+	      v[4] -= x[j][0] * delz * cforce;
+	      v[5] -= x[j][1] * delz * cforce;
+	      vlist[n++] = j;
+	    }
 	  
-	} else {
+	  } else {
 	  
-	  fd[0] = -delx*cforce;
-	  fd[1] = -dely*cforce;
-	  fd[2] = -delz*cforce;
+	    fd[0] = -delx*cforce;
+	    fd[1] = -dely*cforce;
+	    fd[2] = -delz*cforce;
 	  
-	  delxOM = x[j][0] - x2[0];
-	  delyOM = x[j][1] - x2[1];
-	  delzOM = x[j][2] - x2[2];
+	    delxOM = x[j][0] - x2[0];
+	    delyOM = x[j][1] - x2[1];
+	    delzOM = x[j][2] - x2[2];
 	  
-	  ddotf = (delxOM * fd[0] + delyOM * fd[1] + delzOM * fd[2]) /
-	    (qdist*qdist);
+	    ddotf = (delxOM * fd[0] + delyOM * fd[1] + delzOM * fd[2]) /
+	      (qdist*qdist);
 	  
-	  f1[0] = ddotf * delxOM;
-	  f1[1] = ddotf * delyOM;
-	  f1[2] = ddotf * delzOM;
+	    f1[0] = ddotf * delxOM;
+	    f1[1] = ddotf * delyOM;
+	    f1[2] = ddotf * delzOM;
 	  
-	  fO[0] = fd[0] - alpha * (fd[0] - f1[0]);
-	  fO[1] = fd[1] - alpha * (fd[1] - f1[1]);
-	  fO[2] = fd[2] - alpha * (fd[2] - f1[2]);
+	    fO[0] = fd[0] - alpha * (fd[0] - f1[0]);
+	    fO[1] = fd[1] - alpha * (fd[1] - f1[1]);
+	    fO[2] = fd[2] - alpha * (fd[2] - f1[2]);
 	  
-	  fH[0] = 0.5 * alpha * (fd[0] - f1[0]);
-	  fH[1] = 0.5 * alpha * (fd[1] - f1[1]);
-	  fH[2] = 0.5 * alpha * (fd[2] - f1[2]);
+	    fH[0] = 0.5 * alpha * (fd[0] - f1[0]);
+	    fH[1] = 0.5 * alpha * (fd[1] - f1[1]);
+	    fH[2] = 0.5 * alpha * (fd[2] - f1[2]);
 	  
-	  f[j][0] += fO[0];
-	  f[j][1] += fO[1];
-	  f[j][2] += fO[2];
+	    f[j][0] += fO[0];
+	    f[j][1] += fO[1];
+	    f[j][2] += fO[2];
 	  
-	  f[jH1][0] += fH[0];
-	  f[jH1][1] += fH[1];
-	  f[jH1][2] += fH[2];
+	    f[jH1][0] += fH[0];
+	    f[jH1][1] += fH[1];
+	    f[jH1][2] += fH[2];
 	  
-	  f[jH2][0] += fH[0];
-	  f[jH2][1] += fH[1];
-	  f[jH2][2] += fH[2];
+	    f[jH2][0] += fH[0];
+	    f[jH2][1] += fH[1];
+	    f[jH2][2] += fH[2];
 	  
-	  if (vflag) {
-	    domain->closest_image(x[j],x[jH1],xH1);
-	    domain->closest_image(x[j],x[jH2],xH2);
+	    if (vflag) {
+	      domain->closest_image(x[j],x[jH1],xH1);
+	      domain->closest_image(x[j],x[jH2],xH2);
 	    
-	    v[0] += x[j][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0];
-	    v[1] += x[j][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1];
-	    v[2] += x[j][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2];
-	    v[3] += x[j][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1];
-	    v[4] += x[j][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2];
-	    v[5] += x[j][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2];
+	      v[0] += x[j][0]*fO[0] + xH1[0]*fH[0] + xH2[0]*fH[0];
+	      v[1] += x[j][1]*fO[1] + xH1[1]*fH[1] + xH2[1]*fH[1];
+	      v[2] += x[j][2]*fO[2] + xH1[2]*fH[2] + xH2[2]*fH[2];
+	      v[3] += x[j][0]*fO[1] + xH1[0]*fH[1] + xH2[0]*fH[1];
+	      v[4] += x[j][0]*fO[2] + xH1[0]*fH[2] + xH2[0]*fH[2];
+	      v[5] += x[j][1]*fO[2] + xH1[1]*fH[2] + xH2[1]*fH[2];
 	    
-	    vlist[n++] = j;
-	    vlist[n++] = jH1;
-	    vlist[n++] = jH2;
+	      vlist[n++] = j;
+	      vlist[n++] = jH1;
+	      vlist[n++] = jH2;
+	    }
 	  }
-	}
 	
-	if (eflag) {
-	  if (!ncoultablebits || rsq <= tabinnersq)
-	    ecoul = prefactor*erfc;
-	  else {
-	    table = etable[itable] + fraction*detable[itable];
-	    ecoul = qtmp*q[j] * table;
-	  }
-	  if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
-	} else ecoul = 0.0;
+	  if (eflag) {
+	    if (!ncoultablebits || rsq <= tabinnersq)
+	      ecoul = prefactor*erfc;
+	    else {
+	      table = etable[itable] + fraction*detable[itable];
+	      ecoul = qtmp*q[j] * table;
+	    }
+	    if (factor_coul < 1.0) ecoul -= (1.0-factor_coul)*prefactor;
+	  } else ecoul = 0.0;
 	
-	if (evflag) ev_tally_list(n,vlist,ecoul,v);
+	  if (evflag) ev_tally_list(n,vlist,ecoul,v);
+	}
       }
     }
   }
@@ -401,6 +406,7 @@ void PairLJCutCoulLongTIP4P::init_style()
     error->all(FLERR,
 	       "Pair style lj/cut/coul/long/tip4p requires atom attribute q");
   if ( (strcmp(force->kspace_style,"pppm/tip4p") != 0) &&
+       (strcmp(force->kspace_style,"pppm/tip4p/omp") != 0) &&
        (strcmp(force->kspace_style,"pppm/tip4p/proxy") != 0) )
     error->all(FLERR,"Pair style is incompatible with KSpace style");
   if (force->bond == NULL)
diff --git a/src/Makefile b/src/Makefile
index 998a29deed..74dfca755e 100755
--- a/src/Makefile
+++ b/src/Makefile
@@ -20,6 +20,8 @@ PACKAGE = asphere class2 colloid dipole fld gpu granular kim \
 PACKUSER = user-misc user-atc user-awpmd user-cg-cmm \
 	   user-cuda user-eff user-ewaldn user-omp user-reaxc user-sph
 
+PACKLIB = gpu kim meam poems reax user-atc user-awpmd user-cuda
+
 PACKALL = $(PACKAGE) $(PACKUSER)
 
 PACKAGEUC = $(shell echo $(PACKAGE) | tr a-z A-Z)
@@ -48,6 +50,7 @@ help:
 	@echo 'make no-standard         remove all standard packages'
 	@echo 'make yes-user            install all user packages'
 	@echo 'make no-user             remove all user packages'
+	@echo 'make no-lib              remove all packages with external libs'
 	@echo ''
 	@echo 'make package-update      replace src files with package files'
 	@echo 'make package-overwrite   replace package files with src files'
@@ -132,6 +135,7 @@ package:
 	@echo 'make no-standard         remove all standard packages'
 	@echo 'make yes-user            install all user packages'
 	@echo 'make no-user             remove all user packages'
+	@echo 'make no-lib              remove all packages with external libs'
 	@echo ''
 	@echo 'make package-update      replace src files with package files'
 	@echo 'make package-overwrite   replace package files with src files'
@@ -155,6 +159,9 @@ yes-user:
 no-user:
 	@for p in $(PACKUSER); do $(MAKE) no-$$p; done
 
+no-lib:
+	@for p in $(PACKLIB); do $(MAKE) no-$$p; done
+
 yes-%:
 	@if [ ! -e Makefile.package ]; \
 	  then cp Makefile.package.empty Makefile.package; fi
diff --git a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp
index aee802db21..4cb1e11bff 100644
--- a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp
+++ b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.cpp
@@ -77,8 +77,8 @@ void PairLJCutCoulLongTIP4POpt::compute(int eflag, int vflag)
   }
 
   // cache corrected M positions in mpos[]
-  double **x = atom->x;
-  int *type = atom->type;
+  const double * const * const x = atom->x;
+  const int * const type = atom->type;
   for (int i = 0; i < nlocal; i++) {
     if (type[i] == typeO) {
       find_M(i,h1idx[i],h2idx[i],mpos[i]);
@@ -101,56 +101,30 @@ void PairLJCutCoulLongTIP4POpt::compute(int eflag, int vflag)
   if (!ncoultablebits) {
     if (evflag) {
       if (eflag) {
-	if (vflag) {
-	  if (force->newton_pair) return eval<1,1,1,1,0>();
-	  else return eval<1,1,1,0,0>();
-	} else {
-	  if (force->newton_pair) return eval<1,1,0,1,0>();
-	  else return eval<1,1,0,0,0>();
-	} 
+	if (vflag) return eval<1,1,1,1>();
+	else return eval<1,1,1,0>();
       } else {
-	if (vflag) {
-	  if (force->newton_pair) return eval<1,0,1,1,0>();
-	  else return eval<1,0,1,0,0>();
-	} else {
-	  if (force->newton_pair) return eval<1,0,0,1,0>();
-	  else return eval<1,0,0,0,0>();
-	}
+	if (vflag) return eval<1,1,0,1>();
+	else return eval<1,1,0,0>();
       }
-    } else {
-      if (force->newton_pair) return eval<0,0,0,1,0>();
-      else return eval<0,0,0,0,0>();
-    }
+    } else return eval<1,0,0,0>();
   } else {
     if (evflag) {
       if (eflag) {
-	if (vflag) {
-	  if (force->newton_pair) return eval<1,1,1,1,1>();
-	  else return eval<1,1,1,0,1>();
-	} else {
-	  if (force->newton_pair) return eval<1,1,0,1,1>();
-	  else return eval<1,1,0,0,1>();
-	}
+	if (vflag) return eval<0,1,1,1>();
+	else return eval<0,1,1,0>();
       } else {
-	if (vflag) {
-	  if (force->newton_pair) return eval<1,0,1,1,1>();
-	  else return eval<1,0,1,0,1>();
-	} else {
-	  if (force->newton_pair) return eval<1,0,0,1,1>();
-	  else return eval<1,0,0,0,1>();
-	}
+	if (vflag) return eval<0,1,0,1>();
+	else return eval<0,1,0,0>();
       }
-    } else {
-      if (force->newton_pair) return eval<0,0,0,1,1>();
-      else return eval<0,0,0,0,1>();
-    }
+    } else return eval<0,0,0,0>();
   }
 }
 
 /* ---------------------------------------------------------------------- */
 
-template < const int EVFLAG, const int EFLAG, const int VFLAG,
-           const int NEWTON_PAIR, const int CTABLE >
+template < const int CTABLE, const int EVFLAG, 
+	   const int EFLAG, const int VFLAG>
 void PairLJCutCoulLongTIP4POpt::eval()
 {
   int i,j,ii,jj,inum,jnum,itype,jtype,itable;
@@ -158,27 +132,27 @@ void PairLJCutCoulLongTIP4POpt::eval()
   int iH1,iH2,jH1,jH2;
   double qtmp,xtmp,ytmp,ztmp,delx,dely,delz,evdwl,ecoul;
   double fraction,table;
-  double delxOM, delyOM, delzOM;
-  double r,r2inv,r6inv,forcecoul,forcelj,cforce;
+  double delxOM,delyOM,delzOM;
+  double r,rsq,r2inv,r6inv,forcecoul,forcelj,cforce;
   double factor_coul,factor_lj;
   double grij,expm2,prefactor,t,erfc,ddotf;
   double v[6],xH1[3],xH2[3];
   double fdx,fdy,fdz,f1x,f1y,f1z,fOx,fOy,fOz,fHx,fHy,fHz;
   double *x1,*x2;
   int *ilist,*jlist,*numneigh,**firstneigh;
-  double rsq;
 
   evdwl = ecoul = 0.0;
 
-  double **f = atom->f;
-  double **x = atom->x;
-  double *q = atom->q;
-  int *type = atom->type;
-  int nlocal = atom->nlocal;
-  double *special_coul = force->special_coul;
-  double *special_lj = force->special_lj;
-  int newton_pair = force->newton_pair;
-  double qqrd2e = force->qqrd2e;
+  const double * const * const x = atom->x;
+  double * const * const f = atom->f;
+  const double * const q = atom->q;
+  const int * const type = atom->type;
+  const int nlocal = atom->nlocal;
+  const double * const special_coul = force->special_coul;
+  const double * const special_lj = force->special_lj;
+  const double qqrd2e = force->qqrd2e;
+  const double cut_coulsqplus = (cut_coul+2.0*qdist) * (cut_coul+2.0*qdist);
+
   double fxtmp,fytmp,fztmp;
 
   inum = list->inum;
@@ -214,34 +188,36 @@ void PairLJCutCoulLongTIP4POpt::eval()
       delz = ztmp - x[j][2];
       rsq = delx*delx + dely*dely + delz*delz;
       jtype = type[j];
-      
-      if (rsq < cutsq[itype][jtype]) {
 
-	r2inv = 1.0/rsq;
-
-	if (rsq < cut_ljsq[itype][jtype]) {
-	  r6inv = r2inv*r2inv*r2inv;
-	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
-	  forcelj *= factor_lj * r2inv;
-
-	  fxtmp += delx*forcelj;
-	  fytmp += dely*forcelj;
-	  fztmp += delz*forcelj;
-	  f[j][0] -= delx*forcelj;
-	  f[j][1] -= dely*forcelj;
-	  f[j][2] -= delz*forcelj;
+      // LJ interaction based on true rsq
 
-	  if (EFLAG) {
-	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
-	      offset[itype][jtype];
-	    evdwl *= factor_lj;
-	  } else evdwl = 0.0;
+      if (rsq < cut_ljsq[itype][jtype]) {
+	r2inv = 1.0/rsq;
+	r6inv = r2inv*r2inv*r2inv;
+	forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+	forcelj *= factor_lj * r2inv;
+
+	fxtmp += delx*forcelj;
+	fytmp += dely*forcelj;
+	fztmp += delz*forcelj;
+	f[j][0] -= delx*forcelj;
+	f[j][1] -= dely*forcelj;
+	f[j][2] -= delz*forcelj;
+
+	if (EFLAG) {
+	  evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+	    offset[itype][jtype];
+	  evdwl *= factor_lj;
+	} else evdwl = 0.0;
+
+	if (EVFLAG) ev_tally(i,j,nlocal,/* newton_pair = */ 1,
+			     evdwl,0.0,forcelj,delx,dely,delz);
+      }
 
-	  if (EVFLAG) ev_tally(i,j,nlocal,newton_pair,
-			       evdwl,0.0,forcelj,delx,dely,delz);
-	}
+      // adjust rsq and delxyz for off-site O charge(s),
+      // but only if they are within reach
 
-	// adjust rsq and delxyz for off-site O charge(s)
+      if (rsq < cut_coulsqplus) {
 
 	if (itype == typeO || jtype == typeO) {
 	  x2 = mpos[j];
@@ -254,12 +230,12 @@ void PairLJCutCoulLongTIP4POpt::eval()
 	  delz = x1[2] - x2[2];
 	  rsq = delx*delx + dely*dely + delz*delz;
 	}
-
-	// test current rsq against cutoff and compute Coulombic force
+      
+	// Coulombic interaction based on modified rsq
 
 	if (rsq < cut_coulsq) {
 	  r2inv = 1 / rsq;
-	  if (!CTABLE || rsq <= tabinnersq) {
+	  if (CTABLE || rsq <= tabinnersq) {
 	    r = sqrt(rsq);
 	    grij = g_ewald * r;
 	    expm2 = exp(-grij*grij);
@@ -314,40 +290,40 @@ void PairLJCutCoulLongTIP4POpt::eval()
 
 	  } else {
 
-            fdx = delx*cforce;
-            fdy = dely*cforce;
-            fdz = delz*cforce;
+	    fdx = delx*cforce;
+	    fdy = dely*cforce;
+	    fdz = delz*cforce;
 
-            delxOM = x[i][0] - x1[0];
-            delyOM = x[i][1] - x1[1];
-            delzOM = x[i][2] - x1[2];
+	    delxOM = x[i][0] - x1[0];
+	    delyOM = x[i][1] - x1[1];
+	    delzOM = x[i][2] - x1[2];
 
-            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+	    ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
 	      (qdist*qdist);
 
 	    f1x = alpha * (fdx - ddotf * delxOM);
 	    f1y = alpha * (fdy - ddotf * delyOM);
 	    f1z = alpha * (fdz - ddotf * delzOM);
 
-            fOx = fdx - f1x;
-            fOy = fdy - f1y;
-            fOz = fdz - f1z;
+	    fOx = fdx - f1x;
+	    fOy = fdy - f1y;
+	    fOz = fdz - f1z;
 
-            fHx = 0.5 * f1x;
-            fHy = 0.5 * f1y;
-            fHz = 0.5 * f1z;
+	    fHx = 0.5 * f1x;
+	    fHy = 0.5 * f1y;
+	    fHz = 0.5 * f1z;
 
-            fxtmp += fOx;
-            fytmp += fOy;
-            fztmp += fOz;
+	    fxtmp += fOx;
+	    fytmp += fOy;
+	    fztmp += fOz;
 
-            f[iH1][0] += fHx;
-            f[iH1][1] += fHy;
-            f[iH1][2] += fHz;
+	    f[iH1][0] += fHx;
+	    f[iH1][1] += fHy;
+	    f[iH1][2] += fHz;
 
-            f[iH2][0] += fHx;
-            f[iH2][1] += fHy;
-            f[iH2][2] += fHz;
+	    f[iH2][0] += fHx;
+	    f[iH2][1] += fHy;
+	    f[iH2][2] += fHz;
 
 	    if (VFLAG) {
 	      domain->closest_image(x[i],x[iH1],xH1);
@@ -391,32 +367,32 @@ void PairLJCutCoulLongTIP4POpt::eval()
 	    delyOM = x[j][1] - x2[1];
 	    delzOM = x[j][2] - x2[2];
 
-            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+	    ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
 	      (qdist*qdist);
 
 	    f1x = alpha * (fdx - ddotf * delxOM);
 	    f1y = alpha * (fdy - ddotf * delyOM);
 	    f1z = alpha * (fdz - ddotf * delzOM);
 
-            fOx = fdx - f1x;
-            fOy = fdy - f1y;
-            fOz = fdz - f1z;
+	    fOx = fdx - f1x;
+	    fOy = fdy - f1y;
+	    fOz = fdz - f1z;
 
-            fHx = 0.5 * f1x;
-            fHy = 0.5 * f1y;
-            fHz = 0.5 * f1z;
+	    fHx = 0.5 * f1x;
+	    fHy = 0.5 * f1y;
+	    fHz = 0.5 * f1z;
 
 	    f[j][0] += fOx;
 	    f[j][1] += fOy;
 	    f[j][2] += fOz;
 
-            f[jH1][0] += fHx;
-            f[jH1][1] += fHy;
-            f[jH1][2] += fHz;
+	    f[jH1][0] += fHx;
+	    f[jH1][1] += fHy;
+	    f[jH1][2] += fHz;
 
-            f[jH2][0] += fHx;
-            f[jH2][1] += fHy;
-            f[jH2][2] += fHz;
+	    f[jH2][0] += fHx;
+	    f[jH2][1] += fHy;
+	    f[jH2][2] += fHz;
 
 	    if (VFLAG) {
 	      domain->closest_image(x[j],x[jH1],xH1);
@@ -436,7 +412,7 @@ void PairLJCutCoulLongTIP4POpt::eval()
 	  }
 
 	  if (EFLAG) {
-	    if (!CTABLE || rsq <= tabinnersq)
+	    if (CTABLE || rsq <= tabinnersq)
 	      ecoul = prefactor*erfc;
 	    else {
 	      table = etable[itable] + fraction*detable[itable];
diff --git a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
index 5f6f111ae9..4f77ca7c02 100644
--- a/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
+++ b/src/OPT/pair_lj_cut_coul_long_tip4p_opt.h
@@ -39,7 +39,7 @@ class PairLJCutCoulLongTIP4POpt : public PairLJCutCoulLongTIP4P {
   double **mpos;      // coordinates corrected for m-shift.
   void find_M_permissive(int, int &, int &, double *);
 
-  template < const int, const int, const int, const int, const int >
+  template < const int, const int, const int, const int >
   void eval();
 
 };
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
index 04c225db44..b9d83250c3 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.cpp
@@ -42,6 +42,11 @@ PairLJCutCoulLongTIP4POMP::PairLJCutCoulLongTIP4POMP(LAMMPS *lmp) :
   suffix_flag |= Suffix::OMP;
   respa_enable = 0;
 
+  // TIP4P cannot compute virial as F dot r
+  // due to find_M() finding bonded H atoms which are not near O atom
+
+  no_virial_fdotr_compute = 1;
+
   // for caching m-shift corrected positions
   maxmpos = 0;
   h1idx = h2idx = NULL;
@@ -111,17 +116,28 @@ void PairLJCutCoulLongTIP4POMP::compute(int eflag, int vflag)
     ThrData *thr = fix->get_thr(tid);
     ev_setup_thr(eflag, vflag, nall, eatom, vatom, thr);
 
+  if (!ncoultablebits) {
     if (evflag) {
       if (eflag) {
-	if (vflag) eval<1,1,1>(ifrom, ito, thr);
-	else eval<1,1,0>(ifrom, ito, thr);
+	if (vflag) eval<1,1,1,1>(ifrom, ito, thr);
+	else eval<1,1,1,0>(ifrom, ito, thr);
       } else {
-	if (vflag) eval<1,0,1>(ifrom, ito, thr);
-	else eval<1,0,0>(ifrom, ito, thr);
+	if (vflag) eval<1,1,0,1>(ifrom, ito, thr);
+	else eval<1,1,0,0>(ifrom, ito, thr);
       }
-    } else {
-      eval<0,0,0>(ifrom, ito, thr);
-    }
+    } else eval<1,0,0,0>(ifrom, ito, thr);
+  } else {
+    if (evflag) {
+      if (eflag) {
+	if (vflag) eval<0,1,1,1>(ifrom, ito, thr);
+	else eval<0,1,1,0>(ifrom, ito, thr);
+      } else {
+	if (vflag) eval<0,1,0,1>(ifrom, ito, thr);
+	else eval<0,1,0,0>(ifrom, ito, thr);
+      }
+    } else eval<0,0,0,0>(ifrom, ito, thr);
+  }
+  
 
     reduce_thr(this, eflag, vflag, thr);
   } // end of omp parallel region
@@ -129,7 +145,7 @@ void PairLJCutCoulLongTIP4POMP::compute(int eflag, int vflag)
 
 /* ---------------------------------------------------------------------- */
 
-template <int EVFLAG, int EFLAG, int VFLAG>
+template <const int CTABLE, const int EVFLAG, const int EFLAG, const int VFLAG>
 void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 {
   int i,j,ii,jj,jnum,itype,jtype,itable;
@@ -157,6 +173,8 @@ void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
   const double * const special_coul = force->special_coul;
   const double * const special_lj = force->special_lj;
   const double qqrd2e = force->qqrd2e;
+  const double cut_coulsqplus = (cut_coul+2.0*qdist) * (cut_coul+2.0*qdist);
+
   double fxtmp,fytmp,fztmp;
 
   ilist = list->ilist;
@@ -193,34 +211,37 @@ void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
       rsq = delx*delx + dely*dely + delz*delz;
       jtype = type[j];
 
-      if (rsq < cutsq[itype][jtype]) {
+      // LJ interaction based on true rsq
 
+      if (rsq < cut_ljsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
-	if (rsq < cut_ljsq[itype][jtype]) {
-	  r6inv = r2inv*r2inv*r2inv;
-	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
-	  forcelj *= factor_lj * r2inv;
-
-	  fxtmp += delx*forcelj;
-	  fytmp += dely*forcelj;
-	  fztmp += delz*forcelj;
-	  f[j][0] -= delx*forcelj;
-	  f[j][1] -= dely*forcelj;
-	  f[j][2] -= delz*forcelj;
-
-	  if (EFLAG) {
-	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
-	      offset[itype][jtype];
-	    evdwl *= factor_lj;
-	  } else evdwl = 0.0;
+	r6inv = r2inv*r2inv*r2inv;
+	forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+	forcelj *= factor_lj * r2inv;
+
+	fxtmp += delx*forcelj;
+	fytmp += dely*forcelj;
+	fztmp += delz*forcelj;
+	f[j][0] -= delx*forcelj;
+	f[j][1] -= dely*forcelj;
+	f[j][2] -= delz*forcelj;
+
+	if (EFLAG) {
+	  evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+	    offset[itype][jtype];
+	  evdwl *= factor_lj;
+	} else evdwl = 0.0;
+
+	if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1,
+				 evdwl,0.0,forcelj,delx,dely,delz,thr);
+      }
 
-	  if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1,
-				   evdwl,0.0,forcelj,delx,dely,delz,thr);
-	}
+      // adjust rsq and delxyz for off-site O charge(s),
+      // but only if they are within reach
 
-	// adjust rsq and delxyz for off-site O charge(s)
+      if (rsq < cut_coulsqplus) {
 
-	if (itype == typeO || jtype == typeO) { 
+	if (itype == typeO || jtype == typeO) {
 	  x2 = mpos[j];
 	  jH1 = h1idx[j];
 	  jH2 = h2idx[j];
@@ -235,11 +256,11 @@ void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 	  rsq = delx*delx + dely*dely + delz*delz;
 	}
 
-	// test current rsq against cutoff and compute Coulombic force
+	// Coulombic interaction based on modified rsq
 
 	if (rsq < cut_coulsq) {
 	  r2inv = 1 / rsq;
-	  if (!ncoultablebits || rsq <= tabinnersq) {
+	  if (CTABLE || rsq <= tabinnersq) {
 	    r = sqrt(rsq);
 	    grij = g_ewald * r;
 	    expm2 = exp(-grij*grij);
@@ -294,40 +315,40 @@ void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 
 	  } else {
 
-            fdx = delx*cforce;
-            fdy = dely*cforce;
-            fdz = delz*cforce;
+	    fdx = delx*cforce;
+	    fdy = dely*cforce;
+	    fdz = delz*cforce;
 
-            delxOM = x[i][0] - x1[0];
-            delyOM = x[i][1] - x1[1];
-            delzOM = x[i][2] - x1[2];
+	    delxOM = x[i][0] - x1[0];
+	    delyOM = x[i][1] - x1[1];
+	    delzOM = x[i][2] - x1[2];
 
-            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+	    ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
 	      (qdist*qdist);
 
 	    f1x = alpha * (fdx - ddotf * delxOM);
 	    f1y = alpha * (fdy - ddotf * delyOM);
 	    f1z = alpha * (fdz - ddotf * delzOM);
 
-            fOx = fdx - f1x;
-            fOy = fdy - f1y;
-            fOz = fdz - f1z;
+	    fOx = fdx - f1x;
+	    fOy = fdy - f1y;
+	    fOz = fdz - f1z;
 
-            fHx = 0.5 * f1x;
-            fHy = 0.5 * f1y;
-            fHz = 0.5 * f1z;
+	    fHx = 0.5 * f1x;
+	    fHy = 0.5 * f1y;
+	    fHz = 0.5 * f1z;
 
-            fxtmp += fOx;
-            fytmp += fOy;
-            fztmp += fOz;
+	    fxtmp += fOx;
+	    fytmp += fOy;
+	    fztmp += fOz;
 
-            f[iH1][0] += fHx;
-            f[iH1][1] += fHy;
-            f[iH1][2] += fHz;
+	    f[iH1][0] += fHx;
+	    f[iH1][1] += fHy;
+	    f[iH1][2] += fHz;
 
-            f[iH2][0] += fHx;
-            f[iH2][1] += fHy;
-            f[iH2][2] += fHz;
+	    f[iH2][0] += fHx;
+	    f[iH2][1] += fHy;
+	    f[iH2][2] += fHz;
 
 	    if (VFLAG) {
 	      domain->closest_image(x[i],x[iH1],xH1);
@@ -371,32 +392,32 @@ void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 	    delyOM = x[j][1] - x2[1];
 	    delzOM = x[j][2] - x2[2];
 
-            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+	    ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
 	      (qdist*qdist);
 
 	    f1x = alpha * (fdx - ddotf * delxOM);
 	    f1y = alpha * (fdy - ddotf * delyOM);
 	    f1z = alpha * (fdz - ddotf * delzOM);
 
-            fOx = fdx - f1x;
-            fOy = fdy - f1y;
-            fOz = fdz - f1z;
+	    fOx = fdx - f1x;
+	    fOy = fdy - f1y;
+	    fOz = fdz - f1z;
 
-            fHx = 0.5 * f1x;
-            fHy = 0.5 * f1y;
-            fHz = 0.5 * f1z;
+	    fHx = 0.5 * f1x;
+	    fHy = 0.5 * f1y;
+	    fHz = 0.5 * f1z;
 
 	    f[j][0] += fOx;
 	    f[j][1] += fOy;
 	    f[j][2] += fOz;
 
-            f[jH1][0] += fHx;
-            f[jH1][1] += fHy;
-            f[jH1][2] += fHz;
+	    f[jH1][0] += fHx;
+	    f[jH1][1] += fHy;
+	    f[jH1][2] += fHz;
 
-            f[jH2][0] += fHx;
-            f[jH2][1] += fHy;
-            f[jH2][2] += fHz;
+	    f[jH2][0] += fHx;
+	    f[jH2][1] += fHy;
+	    f[jH2][2] += fHz;
 
 	    if (VFLAG) {
 	      domain->closest_image(x[j],x[jH1],xH1);
@@ -416,7 +437,7 @@ void PairLJCutCoulLongTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 	  }
 
 	  if (EFLAG) {
-	    if (!ncoultablebits || rsq <= tabinnersq)
+	    if (CTABLE || rsq <= tabinnersq)
 	      ecoul = prefactor*erfc;
 	    else {
 	      table = etable[itable] + fraction*detable[itable];
diff --git a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
index ff49bdcedb..37743abf14 100644
--- a/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_long_tip4p_omp.h
@@ -46,7 +46,7 @@ class PairLJCutCoulLongTIP4POMP : public PairLJCutCoulLongTIP4P, public ThrOMP {
   void find_M_permissive(int, int &, int &, double *);
 
  private:
-  template <int EVFLAG, int EFLAG, int VFLAG>
+  template <int CFLAG, int EVFLAG, int EFLAG, int VFLAG>
   void eval(int ifrom, int ito, ThrData * const thr);
 };
 
diff --git a/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.cpp b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.cpp
index 11ad798052..d4c0362723 100644
--- a/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.cpp
+++ b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.cpp
@@ -14,7 +14,7 @@
 
 #include "math.h"
 #include "pair_lj_cut_coul_pppm_tip4p_omp.h"
-#include "pppm_proxy.h"
+#include "pppm_tip4p_proxy.h"
 #include "atom.h"
 #include "comm.h"
 #include "domain.h"
@@ -74,7 +74,7 @@ void PairLJCutCoulPPPMTIP4POMP::init_style()
   if (strcmp(force->kspace_style,"pppm/tip4p/proxy") != 0)
     error->all(FLERR,"kspace style pppm/tip4p/proxy is required with this pair style");
 
-  kspace = static_cast<PPPMProxy *>(force->kspace);
+  kspace = static_cast<PPPMTIP4PProxy *>(force->kspace);
 
   PairLJCutCoulLongTIP4P::init_style();
 }
@@ -137,19 +137,29 @@ void PairLJCutCoulPPPMTIP4POMP::compute(int eflag, int vflag)
     if (tid < nproxy) {
       kspace->compute_proxy(eflag,vflag);
     } else {
-      if (evflag) {
-	if (eflag) {
-	  if (vflag) eval<1,1,1>(ifrom, ito, thr);
-	  else eval<1,1,0>(ifrom, ito, thr);
-	} else {
-	  if (vflag) eval<1,0,1>(ifrom, ito, thr);
-	  else eval<1,0,0>(ifrom, ito, thr);
-	}
+      if (!ncoultablebits) {
+	if (evflag) {
+	  if (eflag) {
+	    if (vflag) eval<1,1,1,1>(ifrom, ito, thr);
+	    else eval<1,1,1,0>(ifrom, ito, thr);
+	  } else {
+	    if (vflag) eval<1,1,0,1>(ifrom, ito, thr);
+	    else eval<1,1,0,0>(ifrom, ito, thr);
+	  }
+	} else eval<1,0,0,0>(ifrom, ito, thr);
       } else {
-	eval<0,0,0>(ifrom, ito, thr);
+	if (evflag) {
+	  if (eflag) {
+	    if (vflag) eval<0,1,1,1>(ifrom, ito, thr);
+	    else eval<0,1,1,0>(ifrom, ito, thr);
+	  } else {
+	    if (vflag) eval<0,1,0,1>(ifrom, ito, thr);
+	    else eval<0,1,0,0>(ifrom, ito, thr);
+	  }
+	} else eval<0,0,0,0>(ifrom, ito, thr);
       }
     }
-    
+
     sync_threads();
     reduce_thr(this, eflag, vflag, thr, nproxy);
   } // end of omp parallel region
@@ -157,7 +167,7 @@ void PairLJCutCoulPPPMTIP4POMP::compute(int eflag, int vflag)
 
 /* ---------------------------------------------------------------------- */
 
-template <int EVFLAG, int EFLAG, int VFLAG>
+template <const int CTABLE, const int EVFLAG, const int EFLAG, const int VFLAG>
 void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 {
   int i,j,ii,jj,jnum,itype,jtype,itable;
@@ -185,6 +195,8 @@ void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
   const double * const special_coul = force->special_coul;
   const double * const special_lj = force->special_lj;
   const double qqrd2e = force->qqrd2e;
+  const double cut_coulsqplus = (cut_coul+2.0*qdist) * (cut_coul+2.0*qdist);
+
   double fxtmp,fytmp,fztmp;
 
   ilist = list->ilist;
@@ -221,34 +233,37 @@ void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
       rsq = delx*delx + dely*dely + delz*delz;
       jtype = type[j];
 
-      if (rsq < cutsq[itype][jtype]) {
+      // LJ interaction based on true rsq
 
+      if (rsq < cut_ljsq[itype][jtype]) {
 	r2inv = 1.0/rsq;
-	if (rsq < cut_ljsq[itype][jtype]) {
-	  r6inv = r2inv*r2inv*r2inv;
-	  forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
-	  forcelj *= factor_lj * r2inv;
-
-	  fxtmp += delx*forcelj;
-	  fytmp += dely*forcelj;
-	  fztmp += delz*forcelj;
-	  f[j][0] -= delx*forcelj;
-	  f[j][1] -= dely*forcelj;
-	  f[j][2] -= delz*forcelj;
-
-	  if (EFLAG) {
-	    evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
-	      offset[itype][jtype];
-	    evdwl *= factor_lj;
-	  } else evdwl = 0.0;
+	r6inv = r2inv*r2inv*r2inv;
+	forcelj = r6inv * (lj1[itype][jtype]*r6inv - lj2[itype][jtype]);
+	forcelj *= factor_lj * r2inv;
+
+	fxtmp += delx*forcelj;
+	fytmp += dely*forcelj;
+	fztmp += delz*forcelj;
+	f[j][0] -= delx*forcelj;
+	f[j][1] -= dely*forcelj;
+	f[j][2] -= delz*forcelj;
+
+	if (EFLAG) {
+	  evdwl = r6inv*(lj3[itype][jtype]*r6inv-lj4[itype][jtype]) -
+	    offset[itype][jtype];
+	  evdwl *= factor_lj;
+	} else evdwl = 0.0;
+
+	if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1,
+				 evdwl,0.0,forcelj,delx,dely,delz,thr);
+      }
 
-	  if (EVFLAG) ev_tally_thr(this,i,j,nlocal, /* newton_pair = */ 1,
-				   evdwl,0.0,forcelj,delx,dely,delz,thr);
-	}
+      // adjust rsq and delxyz for off-site O charge(s),
+      // but only if they are within reach
 
-	// adjust rsq and delxyz for off-site O charge(s)
+      if (rsq < cut_coulsqplus) {
 
-	if (itype == typeO || jtype == typeO) { 
+	if (itype == typeO || jtype == typeO) {
 	  x2 = mpos[j];
 	  jH1 = h1idx[j];
 	  jH2 = h2idx[j];
@@ -263,11 +278,11 @@ void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 	  rsq = delx*delx + dely*dely + delz*delz;
 	}
 
-	// test current rsq against cutoff and compute Coulombic force
+	// Coulombic interaction based on modified rsq
 
 	if (rsq < cut_coulsq) {
 	  r2inv = 1 / rsq;
-	  if (!ncoultablebits || rsq <= tabinnersq) {
+	  if (CTABLE || rsq <= tabinnersq) {
 	    r = sqrt(rsq);
 	    grij = g_ewald * r;
 	    expm2 = exp(-grij*grij);
@@ -322,40 +337,40 @@ void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 
 	  } else {
 
-            fdx = delx*cforce;
-            fdy = dely*cforce;
-            fdz = delz*cforce;
+	    fdx = delx*cforce;
+	    fdy = dely*cforce;
+	    fdz = delz*cforce;
 
-            delxOM = x[i][0] - x1[0];
-            delyOM = x[i][1] - x1[1];
-            delzOM = x[i][2] - x1[2];
+	    delxOM = x[i][0] - x1[0];
+	    delyOM = x[i][1] - x1[1];
+	    delzOM = x[i][2] - x1[2];
 
-            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+	    ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
 	      (qdist*qdist);
 
 	    f1x = alpha * (fdx - ddotf * delxOM);
 	    f1y = alpha * (fdy - ddotf * delyOM);
 	    f1z = alpha * (fdz - ddotf * delzOM);
 
-            fOx = fdx - f1x;
-            fOy = fdy - f1y;
-            fOz = fdz - f1z;
+	    fOx = fdx - f1x;
+	    fOy = fdy - f1y;
+	    fOz = fdz - f1z;
 
-            fHx = 0.5 * f1x;
-            fHy = 0.5 * f1y;
-            fHz = 0.5 * f1z;
+	    fHx = 0.5 * f1x;
+	    fHy = 0.5 * f1y;
+	    fHz = 0.5 * f1z;
 
-            fxtmp += fOx;
-            fytmp += fOy;
-            fztmp += fOz;
+	    fxtmp += fOx;
+	    fytmp += fOy;
+	    fztmp += fOz;
 
-            f[iH1][0] += fHx;
-            f[iH1][1] += fHy;
-            f[iH1][2] += fHz;
+	    f[iH1][0] += fHx;
+	    f[iH1][1] += fHy;
+	    f[iH1][2] += fHz;
 
-            f[iH2][0] += fHx;
-            f[iH2][1] += fHy;
-            f[iH2][2] += fHz;
+	    f[iH2][0] += fHx;
+	    f[iH2][1] += fHy;
+	    f[iH2][2] += fHz;
 
 	    if (VFLAG) {
 	      domain->closest_image(x[i],x[iH1],xH1);
@@ -399,32 +414,32 @@ void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 	    delyOM = x[j][1] - x2[1];
 	    delzOM = x[j][2] - x2[2];
 
-            ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
+	    ddotf = (delxOM * fdx + delyOM * fdy + delzOM * fdz) /
 	      (qdist*qdist);
 
 	    f1x = alpha * (fdx - ddotf * delxOM);
 	    f1y = alpha * (fdy - ddotf * delyOM);
 	    f1z = alpha * (fdz - ddotf * delzOM);
 
-            fOx = fdx - f1x;
-            fOy = fdy - f1y;
-            fOz = fdz - f1z;
+	    fOx = fdx - f1x;
+	    fOy = fdy - f1y;
+	    fOz = fdz - f1z;
 
-            fHx = 0.5 * f1x;
-            fHy = 0.5 * f1y;
-            fHz = 0.5 * f1z;
+	    fHx = 0.5 * f1x;
+	    fHy = 0.5 * f1y;
+	    fHz = 0.5 * f1z;
 
 	    f[j][0] += fOx;
 	    f[j][1] += fOy;
 	    f[j][2] += fOz;
 
-            f[jH1][0] += fHx;
-            f[jH1][1] += fHy;
-            f[jH1][2] += fHz;
+	    f[jH1][0] += fHx;
+	    f[jH1][1] += fHy;
+	    f[jH1][2] += fHz;
 
-            f[jH2][0] += fHx;
-            f[jH2][1] += fHy;
-            f[jH2][2] += fHz;
+	    f[jH2][0] += fHx;
+	    f[jH2][1] += fHy;
+	    f[jH2][2] += fHz;
 
 	    if (VFLAG) {
 	      domain->closest_image(x[j],x[jH1],xH1);
@@ -444,7 +459,7 @@ void PairLJCutCoulPPPMTIP4POMP::eval(int iifrom, int iito, ThrData * const thr)
 	  }
 
 	  if (EFLAG) {
-	    if (!ncoultablebits || rsq <= tabinnersq)
+	    if (CTABLE || rsq <= tabinnersq)
 	      ecoul = prefactor*erfc;
 	    else {
 	      table = etable[itable] + fraction*detable[itable];
diff --git a/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.h b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.h
index 71da06eb9b..f4a0bf1f53 100644
--- a/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.h
+++ b/src/USER-OMP/pair_lj_cut_coul_pppm_tip4p_omp.h
@@ -48,10 +48,10 @@ class PairLJCutCoulPPPMTIP4POMP : public PairLJCutCoulLongTIP4P, public ThrOMP {
   void find_M_permissive(int, int &, int &, double *);
 
  private:
-  template <int EVFLAG, int EFLAG, int NEWTON_PAIR>
+  template <const int, const int, const int, const int>
   void eval(int ifrom, int ito, ThrData * const thr);
 
-  class PPPMProxy *kspace;
+  class PPPMTIP4PProxy *kspace;
   int nproxy;
 };
 
-- 
GitLab