diff --git a/src/compute_centro_atom.cpp b/src/compute_centro_atom.cpp
index 6c35ba1e8244014cd49516be139948eca11d49a6..9c3bb35e96ad548f261bc467bd1b75fd86620a22 100644
--- a/src/compute_centro_atom.cpp
+++ b/src/compute_centro_atom.cpp
@@ -27,6 +27,7 @@
 #include "force.h"
 #include "pair.h"
 #include "comm.h"
+#include "math_extra.h"
 #include "memory.h"
 #include "error.h"
 
@@ -37,23 +38,42 @@ using namespace LAMMPS_NS;
 ComputeCentroAtom::ComputeCentroAtom(LAMMPS *lmp, int narg, char **arg) :
   Compute(lmp, narg, arg)
 {
-  if (narg != 4) error->all(FLERR,"Illegal compute centro/atom command");
+  if (narg < 4 || narg > 6) error->all(FLERR,"Illegal compute centro/atom command");
 
   if (strcmp(arg[3],"fcc") == 0) nnn = 12;
   else if (strcmp(arg[3],"bcc") == 0) nnn = 8;
   else nnn = force->inumeric(FLERR,arg[3]);
 
+  // default values
+
+  axes_flag = 0;
+  
+  // optional keywords
+  
+  int iarg = 4;
+  while (iarg < narg) {
+    if (strcmp(arg[iarg],"axes") == 0) {
+      if (iarg+2 > narg) error->all(FLERR,"Illegal compute centro/atom command3");
+      if (strcmp(arg[iarg+1],"yes") == 0) axes_flag = 1;
+      else if (strcmp(arg[iarg+1],"no") == 0) axes_flag = 0;
+      else error->all(FLERR,"Illegal compute centro/atom command2");
+      iarg += 2;
+    } else error->all(FLERR,"Illegal compute centro/atom command1");
+  }
+
   if (nnn <= 0 || nnn % 2)
     error->all(FLERR,"Illegal neighbor value for compute centro/atom command");
 
   peratom_flag = 1;
-  size_peratom_cols = 0;
-
+  if (!axes_flag) size_peratom_cols = 0;
+  else size_peratom_cols = 10;
+  
   nmax = 0;
   centro = NULL;
   maxneigh = 0;
   distsq = NULL;
   nearest = NULL;
+  array_atom = NULL;
 }
 
 /* ---------------------------------------------------------------------- */
@@ -63,6 +83,7 @@ ComputeCentroAtom::~ComputeCentroAtom()
   memory->destroy(centro);
   memory->destroy(distsq);
   memory->destroy(nearest);
+  if (axes_flag) memory->destroy(array_atom);
 }
 
 /* ---------------------------------------------------------------------- */
@@ -106,12 +127,21 @@ void ComputeCentroAtom::compute_peratom()
   invoked_peratom = update->ntimestep;
 
   // grow centro array if necessary
+  // grow array_atom array if axes_flag set
 
   if (atom->nmax > nmax) {
-    memory->destroy(centro);
-    nmax = atom->nmax;
-    memory->create(centro,nmax,"centro/atom:centro");
-    vector_atom = centro;
+    if (!axes_flag) {
+      memory->destroy(centro);
+      nmax = atom->nmax;
+      memory->create(centro,nmax,"centro/atom:centro");
+      vector_atom = centro;
+    } else {
+      memory->destroy(centro);
+      memory->destroy(array_atom);
+      nmax = atom->nmax;
+      memory->create(centro,nmax,"centro/atom:centro");
+      memory->create(array_atom,nmax,size_peratom_cols,"centro/atom:array_atom");
+    }
   }
 
   // invoke full neighbor list (will copy or build if necessary)
@@ -174,45 +204,122 @@ void ComputeCentroAtom::compute_peratom()
         }
       }
 
-      // if not nnn neighbors, centro = 0.0
-
-      if (n < nnn) {
-        centro[i] = 0.0;
-        continue;
-      }
-
-      // store nnn nearest neighs in 1st nnn locations of distsq and nearest
-
-      select2(nnn,n,distsq,nearest);
-
-      // R = Ri + Rj for each of npairs i,j pairs among nnn neighbors
-      // pairs = squared length of each R
-
-      n = 0;
-      for (j = 0; j < nnn; j++) {
-        jj = nearest[j];
-        for (k = j+1; k < nnn; k++) {
-          kk = nearest[k];
-          delx = x[jj][0] + x[kk][0] - 2.0*xtmp;
-          dely = x[jj][1] + x[kk][1] - 2.0*ytmp;
-          delz = x[jj][2] + x[kk][2] - 2.0*ztmp;
-          pairs[n++] = delx*delx + dely*dely + delz*delz;
-        }
+      // check whether to include local crystal symmetry axes
+      
+      if (!axes_flag) {
+	
+	// if not nnn neighbors, centro = 0.0
+
+	if (n < nnn) {
+	  centro[i] = 0.0;
+	  continue;
+	}
+
+	// store nnn nearest neighs in 1st nnn locations of distsq and nearest
+
+	select2(nnn,n,distsq,nearest);
+
+	// R = Ri + Rj for each of npairs i,j pairs among nnn neighbors
+	// pairs = squared length of each R
+
+	n = 0;
+	for (j = 0; j < nnn; j++) {
+	  jj = nearest[j];
+	  for (k = j+1; k < nnn; k++) {
+	    kk = nearest[k];
+	    delx = x[jj][0] + x[kk][0] - 2.0*xtmp;
+	    dely = x[jj][1] + x[kk][1] - 2.0*ytmp;
+	    delz = x[jj][2] + x[kk][2] - 2.0*ztmp;
+	    pairs[n++] = delx*delx + dely*dely + delz*delz;
+
+	  }
+	}
+	
+      } else {
+	
+	// calculate local crystal symmetry axes
+
+	// rsq1, rsq2 are two smallest values of R^2 
+	// R1, R2 are corresponding vectors Ri - Rj
+	// R3 is normal to R1, R2
+
+	double rsq1,rsq2;
+
+	double* r1 = &array_atom[i][1];
+	double* r2 = &array_atom[i][4];
+	double* r3 = &array_atom[i][7];
+	
+	if (n < nnn) {
+	  centro[i] = 0.0;
+	  MathExtra::zero3(r1);
+	  MathExtra::zero3(r2);
+	  MathExtra::zero3(r3);
+	  continue;
+	}
+
+	// store nnn nearest neighs in 1st nnn locations of distsq and nearest
+
+	select2(nnn,n,distsq,nearest);
+
+	n = 0;
+	rsq1 = rsq2 = cutsq;
+	for (j = 0; j < nnn; j++) {
+	  jj = nearest[j];
+	  for (k = j+1; k < nnn; k++) {
+	    kk = nearest[k];
+	    delx = x[jj][0] + x[kk][0] - 2.0*xtmp;
+	    dely = x[jj][1] + x[kk][1] - 2.0*ytmp;
+	    delz = x[jj][2] + x[kk][2] - 2.0*ztmp;
+	    double rsq = delx*delx + dely*dely + delz*delz;
+	    pairs[n++] = rsq;
+	    
+	    if (rsq < rsq2)
+	      if (rsq < rsq1) {
+		rsq2 = rsq1;
+		MathExtra::copy3(r1, r2);
+		rsq1 = rsq;
+		MathExtra::sub3(x[jj],x[kk],r1);
+	      } else {
+		rsq2 = rsq;
+		MathExtra::sub3(x[jj],x[kk],r2);
+	      }
+	  }
+	}
+
+	MathExtra::cross3(r1,r2,r3);
+	MathExtra::norm3(r1);
+	MathExtra::norm3(r2);
+	MathExtra::norm3(r3);
       }
-
+      
       // store nhalf smallest pair distances in 1st nhalf locations of pairs
-
+      
       select(nhalf,npairs,pairs);
-
+      
       // centrosymmetry = sum of nhalf smallest squared values
 
       value = 0.0;
       for (j = 0; j < nhalf; j++) value += pairs[j];
       centro[i] = value;
-    } else centro[i] = 0.0;
+
+    } else {
+      centro[i] = 0.0;
+      if (axes_flag) {
+	MathExtra::zero3(&array_atom[i][1]);
+	MathExtra::zero3(&array_atom[i][4]);
+	MathExtra::zero3(&array_atom[i][7]);
+      }
+    }
   }
 
   delete [] pairs;
+
+  if (axes_flag)
+    for (ii = 0; ii < inum; ii++) {
+      i = ilist[ii];
+      if (mask[i] & groupbit)
+	array_atom[i][0] = centro[i];
+    }
 }
 
 /* ----------------------------------------------------------------------
diff --git a/src/compute_centro_atom.h b/src/compute_centro_atom.h
index 6575e3fb5808d587ddd7525f0f76769ac166757d..ef3128ee68e5ac9ba89e8a25d833b5d73a1fb553 100644
--- a/src/compute_centro_atom.h
+++ b/src/compute_centro_atom.h
@@ -39,7 +39,8 @@ class ComputeCentroAtom : public Compute {
   int *nearest;
   class NeighList *list;
   double *centro;
-
+  int axes_flag;
+  
   void select(int, int, double *);
   void select2(int, int, double *, int *);
 };
diff --git a/src/math_extra.h b/src/math_extra.h
index 4e6ee4c77c3886ba2e73552e83f61dd66c3b1170..0bfc7193a4e31622af2b58db0a0c3b2af97e6d64 100755
--- a/src/math_extra.h
+++ b/src/math_extra.h
@@ -27,12 +27,15 @@ namespace MathExtra {
 
   // 3 vector operations
 
+  inline void copy3(const double *v, double *ans);
+  inline void zero3(double *v);
   inline void norm3(double *v);
   inline void normalize3(const double *v, double *ans);
   inline void snormalize3(const double, const double *v, double *ans);
   inline void negate3(double *v);
   inline void scale3(double s, double *v);
   inline void add3(const double *v1, const double *v2, double *ans);
+  inline void scaleadd3(double s, const double *v1, const double *v2, double *ans);
   inline void sub3(const double *v1, const double *v2, double *ans);
   inline double len3(const double *v);
   inline double lensq3(const double *v);
@@ -128,6 +131,28 @@ namespace MathExtra {
                         double *inertia);
 }
 
+/* ----------------------------------------------------------------------
+   copy a vector, return in ans
+------------------------------------------------------------------------- */
+
+inline void MathExtra::copy3(const double *v, double *ans)
+{
+  ans[0] = v[0];
+  ans[1] = v[1];
+  ans[2] = v[2];
+}
+
+/* ----------------------------------------------------------------------
+   set vector equal to zero
+------------------------------------------------------------------------- */
+
+inline void MathExtra::zero3(double *v)
+{
+  v[0] = 0.0;
+  v[1] = 0.0;
+  v[2] = 0.0;
+}
+
 /* ----------------------------------------------------------------------
    normalize a vector in place
 ------------------------------------------------------------------------- */
@@ -198,6 +223,17 @@ inline void MathExtra::add3(const double *v1, const double *v2, double *ans)
   ans[2] = v1[2] + v2[2];
 }
 
+/* ----------------------------------------------------------------------
+   ans = s*v1 + v2
+------------------------------------------------------------------------- */
+
+inline void MathExtra::scaleadd3(double s, const double *v1, const double *v2, double *ans)
+{
+  ans[0] = s*v1[0] + v2[0];
+  ans[1] = s*v1[1] + v2[1];
+  ans[2] = s*v1[2] + v2[2];
+}
+
 /* ----------------------------------------------------------------------
    ans = v1 - v2
 ------------------------------------------------------------------------- */