diff --git a/src/fix_nh.cpp b/src/fix_nh.cpp
index 1b943978da734f5880023ad78f2c928f627b9baa..edf6d14a404ab663cb062117446adbcbde7cb773 100644
--- a/src/fix_nh.cpp
+++ b/src/fix_nh.cpp
@@ -567,8 +567,6 @@ void FixNH::setup(int vflag)
 {
   // initialize some quantities that were not available earlier
 
-  if (mtk_flag) mtk_factor = 1.0 + 1.0/atom->natoms;
-  else mtk_factor = 1.0;
   tdof = temperature->dof;
 
   // t_target is used by compute_scalar(), even for NPH
@@ -639,9 +637,6 @@ void FixNH::setup(int vflag)
 	   boltz*t_target) / etap_mass[ich];
     }
 
-    // compute appropriately coupled elements of mvv_current
-
-    if (mtk_flag) couple_ke();
   }
 }
 
@@ -681,7 +676,6 @@ void FixNH::initial_integrate(int vflag)
     }
     couple();
     pressure->addstep(update->ntimestep+1);
-    if (mtk_flag) couple_ke();
   }
 
   if (pstat_flag) {
@@ -726,7 +720,6 @@ void FixNH::final_integrate()
     else pressure->compute_vector();
     couple();
     pressure->addstep(update->ntimestep+1);
-    if (mtk_flag) couple_ke();
   }
 
   if (pstat_flag) nh_omega_dot();
@@ -750,7 +743,7 @@ void FixNH::initial_integrate_respa(int vflag, int ilevel, int iloop)
   dtf = 0.5 * step_respa[ilevel] * force->ftm2v;
   dthalf = 0.5 * step_respa[ilevel];
 
-  // outermost level - update eta_dot and omega_dot, apply to v, remap box
+  // outermost level - update eta_dot and omega_dot, apply to v
   // all other levels - NVE update of v
   // x,v updates only performed for atoms in group
 
@@ -786,7 +779,6 @@ void FixNH::initial_integrate_respa(int vflag, int ilevel, int iloop)
       }
       couple();
       pressure->addstep(update->ntimestep+1);
-      if (mtk_flag) couple_ke();
     }
     
     if (pstat_flag) {
@@ -869,37 +861,6 @@ void FixNH::couple()
   }
 }
 
-/* ---------------------------------------------------------------------- */
-
-void FixNH::couple_ke()
-{
-  double *tensor = temperature->vector;
-
-  if (pstyle == ISO)
-    mvv_current[0] = mvv_current[1] = mvv_current[2] = 
-      tdof * boltz * t_current/dimension;
-  else if (pcouple == XYZ) {
-    double ave = 1.0/3.0 * (tensor[0] + tensor[1] + tensor[2]);
-    mvv_current[0] = mvv_current[1] = mvv_current[2] = ave;
-  } else if (pcouple == XY) {
-    double ave = 0.5 * (tensor[0] + tensor[1]);
-    mvv_current[0] = mvv_current[1] = ave;
-    mvv_current[2] = tensor[2];
-  } else if (pcouple == YZ) {
-    double ave = 0.5 * (tensor[1] + tensor[2]);
-    mvv_current[1] = mvv_current[2] = ave;
-    mvv_current[0] = tensor[0];
-  } else if (pcouple == XZ) {
-    double ave = 0.5 * (tensor[0] + tensor[2]);
-    mvv_current[0] = mvv_current[2] = ave;
-    mvv_current[1] = tensor[1];
-  } else {
-    mvv_current[0] = tensor[0];
-    mvv_current[1] = tensor[1];
-    mvv_current[2] = tensor[2];
-  }
-}
-
 /* ----------------------------------------------------------------------
    change box size
    remap all atoms or fix group atoms depending on allremap flag
@@ -914,6 +875,7 @@ void FixNH::remap()
   double **x = atom->x;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
+  double *h = domain->h;
 
   // omega is not used, except for book-keeping
 
@@ -934,15 +896,41 @@ void FixNH::remap()
 
   // reset global and local box to new size/shape
 
+  // This operation corresponds to applying the
+  // translate and scale operations 
+  // corresponding to the solution of the following ODE:
+  //
+  // h_dot = omega_dot * h
+  //
+  // where h_dot, omega_dot and h are all upper-triangular
+  // 3x3 tensors. In Voigt notation, the elements of the 
+  // RHS product tensor are:
+  // h_dot = [0*0, 1*1, 2*2, 1*3+3*2, 0*4+5*3+4*2, 0*5+5*1]
+  // 
+  // Ordering of operations preserves time symmetry.
+
+  double dto2 = dto/2.0;
+  double dto4 = dto/4.0;
+  double dto8 = dto/8.0;
+
   if (pstyle == TRICLINIC) {
-    domain->yz += domain->zprd*dilation[3]; 
-    domain->xz += domain->zprd*dilation[4]; 
-    domain->xy += domain->yprd*dilation[5]; 
-    
-    if (domain->yz < -0.5*domain->yprd || domain->yz > 0.5*domain->yprd ||
-	domain->xz < -0.5*domain->xprd || domain->xz > 0.5*domain->xprd ||
-	domain->xy < -0.5*domain->xprd || domain->xy > 0.5*domain->xprd)
-      error->all("fix npt/nph has tilted box beyond 45 degrees");
+
+    h[4] *= exp(dto8*omega_dot[0]);
+    h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); 
+    h[4] *= exp(dto8*omega_dot[0]);
+
+    h[3] *= exp(dto4*omega_dot[1]);
+    h[3] += dto2*(omega_dot[3]*h[2]); 
+    h[3] *= exp(dto4*omega_dot[1]);
+
+    h[5] *= exp(dto4*omega_dot[0]);
+    h[5] += dto2*(omega_dot[5]*h[1]); 
+    h[5] *= exp(dto4*omega_dot[0]);
+
+    h[4] *= exp(dto8*omega_dot[0]);
+    h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); 
+    h[4] *= exp(dto8*omega_dot[0]);
+
   }
 
   for (i = 0; i < 3; i++) {
@@ -950,11 +938,39 @@ void FixNH::remap()
       oldlo = domain->boxlo[i];
       oldhi = domain->boxhi[i];
       ctr = 0.5 * (oldlo + oldhi);
-      domain->boxlo[i] = (oldlo-ctr)*dilation[i] + ctr;
-      domain->boxhi[i] = (oldhi-ctr)*dilation[i] + ctr;
+      domain->boxlo[i] = (oldlo-ctr)*exp(dto*omega_dot[i]) + ctr;
+      domain->boxhi[i] = (oldhi-ctr)*exp(dto*omega_dot[i]) + ctr;
     }
   }
 
+  if (pstyle == TRICLINIC) {
+
+    h[4] *= exp(dto8*omega_dot[0]);
+    h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); 
+    h[4] *= exp(dto8*omega_dot[0]);
+
+    h[3] *= exp(dto4*omega_dot[1]);
+    h[3] += dto2*(omega_dot[3]*h[2]); 
+    h[3] *= exp(dto4*omega_dot[1]);
+
+    h[5] *= exp(dto4*omega_dot[0]);
+    h[5] += dto2*(omega_dot[5]*h[1]); 
+    h[5] *= exp(dto4*omega_dot[0]);
+
+    h[4] *= exp(dto8*omega_dot[0]);
+    h[4] += dto4*(omega_dot[5]*h[3]+omega_dot[4]*h[2]); 
+    h[4] *= exp(dto8*omega_dot[0]);
+
+    domain->yz = h[3];
+    domain->xz = h[4];
+    domain->xy = h[5];
+
+    if (domain->yz < -0.5*domain->yprd || domain->yz > 0.5*domain->yprd ||
+	domain->xz < -0.5*domain->xprd || domain->xz > 0.5*domain->xprd ||
+	domain->xy < -0.5*domain->xprd || domain->xy > 0.5*domain->xprd)
+      error->all("fix npt/nph has tilted box beyond 45 degrees");
+  }
+
   domain->set_global_box();
   domain->set_local_box();
 
@@ -1566,11 +1582,16 @@ void FixNH::nhc_press_integrate()
 
 void FixNH::nh_v_press()
 {
+  double factor[3];
   double **v = atom->v;
   int *mask = atom->mask;
   int nlocal = atom->nlocal;
   if (igroup == atom->firstgroup) nlocal = atom->nfirst;
 
+  factor[0] = exp(-dt4*(omega_dot[0]+mtk_term2));
+  factor[1] = exp(-dt4*(omega_dot[1]+mtk_term2));
+  factor[2] = exp(-dt4*(omega_dot[2]+mtk_term2));
+
   if (which == NOBIAS) {
     for (int i = 0; i < nlocal; i++) {
       if (mask[i] & groupbit) {
@@ -1578,9 +1599,12 @@ void FixNH::nh_v_press()
 	v[i][1] *= factor[1];
 	v[i][2] *= factor[2];
 	if (pstyle == TRICLINIC) {
-	  v[i][0] += v[i][1]*factor[5] + v[i][2]*factor[4];
-	  v[i][1] += v[i][2]*factor[3];
+	  v[i][0] += -dthalf*(v[i][1]*omega_dot[5] + v[i][2]*omega_dot[4]);
+	  v[i][1] += -dthalf*v[i][2]*omega_dot[3];
 	}
+	v[i][0] *= factor[0];
+	v[i][1] *= factor[1];
+	v[i][2] *= factor[2];
       }
     }
   } else if (which == BIAS) {
@@ -1591,9 +1615,12 @@ void FixNH::nh_v_press()
 	v[i][1] *= factor[1];
 	v[i][2] *= factor[2];
 	if (pstyle == TRICLINIC) {
-	  v[i][0] += v[i][1]*factor[5] + v[i][2]*factor[4];
-	  v[i][1] += v[i][2]*factor[3];
+	  v[i][0] += -dthalf*(v[i][1]*omega_dot[5] + v[i][2]*omega_dot[4]);
+	  v[i][1] += -dthalf*v[i][2]*omega_dot[3];
 	}
+	v[i][0] *= factor[0];
+	v[i][1] *= factor[1];
+	v[i][2] *= factor[2];
 	temperature->restore_bias(i,v[i]);
       }
     }
@@ -1844,38 +1871,50 @@ void FixNH::compute_press_target()
 }
 
 /* ----------------------------------------------------------------------
-   update omega_dot, omega, dilation
+   update omega_dot, omega
 -----------------------------------------------------------------------*/
 
 void FixNH::nh_omega_dot()
 {
-  double mtk_term;
   double f_omega,volume;
+
   if (dimension == 3) volume = domain->xprd*domain->yprd*domain->zprd;
   else volume = domain->xprd*domain->yprd;
 
   if (deviatoric_flag) compute_deviatoric();
 
-  for (int i = 0; i < 3; i++) {    
-
+  mtk_term1 = 0.0;
+  if (mtk_flag)
+    if (pstyle == ISO) { 
+      mtk_term1 = tdof * boltz * t_current;
+      mtk_term1 /= pdim * atom->natoms;
+    } else {
+      double *mvv_current = temperature->vector;
+      for (int i = 0; i < 3; i++)
+	if (p_flag[i])
+	  mtk_term1 += mvv_current[i];
+      mtk_term1 /= pdim * atom->natoms;
+    }
+  
+  for (int i = 0; i < 3; i++)
     if (p_flag[i]) {
-      if (mtk_flag) mtk_term = mvv_current[i]/(atom->natoms*volume) * nktv2p;
-      else mtk_term = 0.0;
-      f_omega = (p_current[i]-p_hydro+mtk_term)*volume /
-	(omega_mass[i] * nktv2p);
+      f_omega = (p_current[i]-p_hydro)*volume /
+	(omega_mass[i] * nktv2p) + mtk_term1 / omega_mass[i];
       if (deviatoric_flag) f_omega -= fdev[i]/(omega_mass[i] * nktv2p);
       omega_dot[i] += f_omega*dthalf;
       omega_dot[i] *= pdrag_factor;
     }
 
-    factor[i] = exp(-dthalf*omega_dot[i]*mtk_factor);
-    dilation[i] = exp(dto*omega_dot[i]);
-
+  mtk_term2 = 0.0;
+  if (mtk_flag) {
+    for (int i = 0; i < 3; i++)
+      if (p_flag[i])
+	mtk_term2 += omega_dot[i];
+    mtk_term2 /= pdim * atom->natoms;
   }
-  
+
   if (pstyle == TRICLINIC) {
     for (int i = 3; i < 6; i++) {
-
       if (p_flag[i]) {
 	f_omega = p_current[i]*volume/(omega_mass[i] * nktv2p);
 	if (deviatoric_flag) 
@@ -1883,10 +1922,6 @@ void FixNH::nh_omega_dot()
 	omega_dot[i] += f_omega*dthalf;
 	omega_dot[i] *= pdrag_factor;
       }
-      
-      factor[i] = -dthalf*omega_dot[i];
-      dilation[i] = dto*omega_dot[i];
-
     } 
   }
 }
diff --git a/src/fix_nh.h b/src/fix_nh.h
index aa6a6edd49bf942a58fe38c199de7a0964c149eb..3edcf3330260775caf55c62d003739aa2514c23b 100644
--- a/src/fix_nh.h
+++ b/src/fix_nh.h
@@ -55,10 +55,9 @@ class FixNH : public Fix {
   double p_freq[6],p_target[6];
   double omega[6],omega_dot[6];
   double omega_mass[6];
-  double p_current[6],dilation[6];
+  double p_current[6];
   double drag,tdrag_factor;        // drag factor on particle thermostat
   double pdrag_factor;             // drag factor on barostat
-  double factor[6];                // velocity scaling due to barostat
   int kspace_flag;                 // 1 if KSpace invoked, 0 if not
   int nrigid;                      // number of rigid fixes
   int *rfix;                       // indices of rigid fixes
@@ -83,8 +82,6 @@ class FixNH : public Fix {
                                    
   int mtk_flag;                    // 0 if using Hoover barostat
   int pdim;                        // number of barostatted dims
-  double mvv_current[3];           // diagonal of KE tensor
-  double mtk_factor;               // MTK factor
   double p_freq_max;               // maximum barostat frequency
 
   double p_hydro;                  // hydrostatic target pressure
@@ -96,9 +93,9 @@ class FixNH : public Fix {
   int deviatoric_flag;             // 0 if target stress tensor is hydrostatic
   double h0_inv[6];                // h_inv of reference (zero strain) box
   int nreset_h0;                   // interval for resetting h0
+  double mtk_term1,mtk_term2;      // Martyna-Tobias-Klein corrections
 
   void couple();
-  void couple_ke();
   void remap();
   void nhc_temp_integrate();
   void nhc_press_integrate();