diff --git a/src/BODY/pair_body_rounded_polygon.cpp b/src/BODY/pair_body_rounded_polygon.cpp
index 9f9cdea31b1abd7e5c7b21e826aa64a3d6db6355..62a6d77a01b94d57cc34fc06e6827df3080fecaf 100644
--- a/src/BODY/pair_body_rounded_polygon.cpp
+++ b/src/BODY/pair_body_rounded_polygon.cpp
@@ -848,6 +848,7 @@ int PairBodyRoundedPolygon::vertex_against_edge(int i, int j,
 
         // done with the edges from body j,
         // given that vertex ni interacts with only one vertex from one edge of body j
+        // comment out this break to take into account concave shapes
 
 //        break;
 
@@ -955,6 +956,7 @@ int PairBodyRoundedPolygon::vertex_against_edge(int i, int j,
 
         // done with the edges from body j,
         // given that vertex ni interacts with only one edge from body j
+        // comment out this break to take into account concave shapes
 
 //        break;
 
@@ -1080,12 +1082,12 @@ int PairBodyRoundedPolygon::compute_distance_to_vertex(int ibody,
     // check if x0 (the queried vertex) and xmi (the body's center of mass)
     // are on the different sides of the edge
 
-    int m = 1;//opposite_sides(xi1, xi2, x0, xmi);
+    int m = opposite_sides(xi1, xi2, x0, xmi);
 
     if (m == 0) {
 
       // x0 and xmi are on not the opposite sides of the edge
-      // leave xpi for another edge to detect --  for convex shapes only
+      // leave xpi for another edge to detect
 
       mode = NONE;
 
diff --git a/src/BODY/pair_body_rounded_polyhedron.cpp b/src/BODY/pair_body_rounded_polyhedron.cpp
index bc94b9cc805cc70cbb2f2f87a2ee015fcb9d10c2..02c2abe1e337edf619f310a583b8faa48d4a3f1e 100644
--- a/src/BODY/pair_body_rounded_polyhedron.cpp
+++ b/src/BODY/pair_body_rounded_polyhedron.cpp
@@ -47,7 +47,7 @@ using namespace MathConst;
 #define DELTA 10000
 #define EPSILON 1e-3
 #define MAX_FACE_SIZE 4 // maximum number of vertices per face (same as BodyRoundedPolyhedron)
-#define MAX_CONTACTS 16  // for 3D models
+#define MAX_CONTACTS 32  // for 3D models
 
 //#define _POLYHEDRON_DEBUG
 
@@ -308,36 +308,8 @@ void PairBodyRoundedPolyhedron::compute(int eflag, int vflag)
       // also consider point contacts and line contacts
 
       if (num_contacts > 0) {
-        double contact_area;
-        if (num_contacts == 1) {
-          contact_area = 0;
-        } else if (num_contacts == 2) {
-          contact_area = num_contacts * A_ua;
-        } else {
-          int m;
-          double xc[3],dx,dy,dz;
-          xc[0] = xc[1] = xc[2] = 0;
-          for (m = 0; m < num_contacts; m++) {
-            xc[0] += contact_list[m].xi[0];
-            xc[1] += contact_list[m].xi[1];
-            xc[2] += contact_list[m].xi[2];
-          }
-
-          xc[0] /= (double)num_contacts;
-          xc[1] /= (double)num_contacts;
-          xc[2] /= (double)num_contacts;
-
-          contact_area = 0.0;
-          for (m = 0; m < num_contacts; m++) {
-            dx = contact_list[m].xi[0] - xc[0];
-            dy = contact_list[m].xi[1] - xc[1];
-            dz = contact_list[m].xi[2] - xc[2];
-            contact_area += (dx*dx + dy*dy + dz*dz);
-          }
-          contact_area *= (MY_PI/(double)num_contacts);
-        }
         rescale_cohesive_forces(x, f, torque, contact_list, num_contacts,
-                                contact_area, k_nij, k_naij, facc);
+                                k_nij, k_naij, facc);
       }
 
       if (evflag) ev_tally_xyz(i,j,nlocal,newton_pair,evdwl,0.0,
@@ -383,6 +355,8 @@ void PairBodyRoundedPolyhedron::settings(int narg, char **arg)
   mu = force->numeric(FLERR,arg[2]);
   A_ua = force->numeric(FLERR,arg[3]);
   cut_inner = force->numeric(FLERR,arg[4]);
+
+  if (A_ua < 0) A_ua = 1;
 }
 
 /* ----------------------------------------------------------------------
@@ -1381,7 +1355,17 @@ int PairBodyRoundedPolyhedron::interaction_face_to_edge(int ibody,
 
     #endif
   } else if (interact == EF_INTERSECT_INSIDE) {
-
+    // need to do something here to resolve overlap!!
+    // p is the intersection between the edge and the face
+    int jflag = 1;
+    if (d1 < d2)
+      pair_force_and_torque(jbody, ibody, xpj1, hi1, d1, contact_dist,
+                            k_n, k_na, shift, x, v, f, torque, angmom,
+                            jflag, energy, facc);
+    else
+      pair_force_and_torque(jbody, ibody, xpj2, hi2, d2, contact_dist,
+                            k_n, k_na, shift, x, v, f, torque, angmom,
+                            jflag, energy, facc);
   }
 
   return interact;
@@ -1661,6 +1645,7 @@ void PairBodyRoundedPolyhedron::contact_forces(int ibody, int jbody,
   ft[1] = -c_t * vt2;
   ft[2] = -c_t * vt3;
 
+  // these are contact forces (F_n, F_t and F_ne) only
   // cohesive forces will be scaled by j_a after contact area is computed
   // mu * fne = tangential friction deformation during gross sliding
   // see Eq. 4, Fraige et al.
@@ -1697,13 +1682,49 @@ void PairBodyRoundedPolyhedron::contact_forces(int ibody, int jbody,
 
 void PairBodyRoundedPolyhedron::rescale_cohesive_forces(double** x,
      double** f, double** torque, Contact* contact_list, int &num_contacts,
-     double contact_area, double k_n, double k_na, double* facc)
+     double k_n, double k_na, double* facc)
 {
   int m,ibody,jbody;
-  double delx,dely,delz,fx,fy,fz,R,fpair,r,shift;
+  double delx,dely,delz,fx,fy,fz,R,fpair,r,shift,contact_area;
+
+  int num_unique_contacts = 0;
+  if (num_contacts == 1) {
+    num_unique_contacts = 1;
+    contact_area = 0;
+  } else if (num_contacts == 2) {
+    num_unique_contacts = 2;
+    contact_area = num_contacts * A_ua;
+  } else {
+    find_unique_contacts(contact_list, num_contacts);
+
+    double xc[3],dx,dy,dz;
+    xc[0] = xc[1] = xc[2] = 0;
+    num_unique_contacts = 0;
+    for (int m = 0; m < num_contacts; m++) {
+      if (contact_list[m].unique == 0) continue;
+      xc[0] += contact_list[m].xi[0];
+      xc[1] += contact_list[m].xi[1];
+      xc[2] += contact_list[m].xi[2];
+      num_unique_contacts++;
+    }
+
+    xc[0] /= (double)num_unique_contacts;
+    xc[1] /= (double)num_unique_contacts;
+    xc[2] /= (double)num_unique_contacts;
+    
+    contact_area = 0.0;
+    for (int m = 0; m < num_contacts; m++) {
+      if (contact_list[m].unique == 0) continue;
+      dx = contact_list[m].xi[0] - xc[0];
+      dy = contact_list[m].xi[1] - xc[1];
+      dz = contact_list[m].xi[2] - xc[2];
+      contact_area += (dx*dx + dy*dy + dz*dz);
+    }
+    contact_area *= (MY_PI/(double)num_unique_contacts);
+  }
+
   double j_a = contact_area / (num_contacts * A_ua);
   if (j_a < 1.0) j_a = 1.0;
-
   shift = k_na * cut_inner;
 
   for (m = 0; m < num_contacts; m++) {
@@ -2302,6 +2323,41 @@ void PairBodyRoundedPolyhedron::total_velocity(double* p, double *xcm,
   vi[2] = omega[0]*r[1] - omega[1]*r[0] + vcm[2];
 }
 
+/* ----------------------------------------------------------------------
+  Determine the length of the contact segment, i.e. the separation between
+  2 contacts, should be extended for 3D models.
+------------------------------------------------------------------------- */
+
+double PairBodyRoundedPolyhedron::contact_separation(const Contact& c1,
+                                                     const Contact& c2)
+{
+  double x1 = 0.5*(c1.xi[0] + c1.xj[0]);
+  double y1 = 0.5*(c1.xi[1] + c1.xj[1]);
+  double z1 = 0.5*(c1.xi[2] + c1.xj[2]);
+  double x2 = 0.5*(c2.xi[0] + c2.xj[0]);
+  double y2 = 0.5*(c2.xi[1] + c2.xj[1]);
+  double z2 = 0.5*(c2.xi[2] + c2.xj[2]);
+  double rsq = (x2 - x1)*(x2 - x1) + (y2 - y1)*(y2 - y1) + (z2 - z1)*(z2 - z1);
+  return rsq;
+}
+
+/* ----------------------------------------------------------------------
+   find the number of unique contacts
+------------------------------------------------------------------------- */
+
+void PairBodyRoundedPolyhedron::find_unique_contacts(Contact* contact_list, int& num_contacts)
+{
+  int n = num_contacts;
+  for (int i = 0; i < n - 1; i++) {
+
+    for (int j = i + 1; j < n; j++) {
+      if (contact_list[i].unique == 0) continue;
+      double d = contact_separation(contact_list[i], contact_list[j]);
+      if (d < EPSILON) contact_list[j].unique = 0;
+    }
+  }
+}
+
 /* ---------------------------------------------------------------------- */
 
 void PairBodyRoundedPolyhedron::sanity_check()
diff --git a/src/BODY/pair_body_rounded_polyhedron.h b/src/BODY/pair_body_rounded_polyhedron.h
index d7ee1f013e66a837948bdd6bddfb5464630e50fe..05985ef813a82790aebd56740525c102f2749130 100644
--- a/src/BODY/pair_body_rounded_polyhedron.h
+++ b/src/BODY/pair_body_rounded_polyhedron.h
@@ -35,12 +35,13 @@ class PairBodyRoundedPolyhedron : public Pair {
   double init_one(int, int);
 
   struct Contact {
-    int ibody, jbody; // body (i.e. atom) indices (not tags)
-    int type;         // 0 = VERTEX-FACE; 1 = EDGE-EDGE
-    double fx,fy,fz;  // unscaled cohesive forces at contact
-    double xi[3];     // coordinates of the contact point on ibody
-    double xj[3];     // coordinates of the contact point on jbody
+    int ibody, jbody;  // body (i.e. atom) indices (not tags)
+    int type;          // 0 = VERTEX-FACE; 1 = EDGE-EDGE
+    double fx,fy,fz;   // unscaled cohesive forces at contact
+    double xi[3];      // coordinates of the contact point on ibody
+    double xj[3];      // coordinates of the contact point on jbody
     double separation; // contact surface separation
+    int unique;
   };
 
  protected:
@@ -124,7 +125,11 @@ class PairBodyRoundedPolyhedron : public Pair {
                              int jflag, double& energy, double* facc);
   void rescale_cohesive_forces(double** x, double** f, double** torque,
                                Contact* contact_list, int &num_contacts,
-                               double contact_area, double k_n, double k_na, double* facc);
+                               double k_n, double k_na, double* facc);
+
+  double contact_separation(const Contact& c1, const Contact& c2);
+
+  void find_unique_contacts(Contact* contact_list, int& num_contacts);
 
   void sum_torque(double* xm, double *x, double fx, double fy, double fz, double* torque);
   int opposite_sides(double* n, double* x0, double* a, double* b);