Index: /trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/hashtable.c
===================================================================
--- /trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/hashtable.c	(revision 8503)
+++ /trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/hashtable.c	(revision 8504)
@@ -20,31 +20,38 @@
 //==============================================================================
 
-struct edge {
-    int key;                    /* key of form i m + j */
+typedef struct  {
+    int i;
+    int j;
+} edge_key_t;
+
+typedef struct {
+    edge_key_t key;              /* key of form i , j */
     int vol_id;                /* id of vol containing this edge */
     int edge_id;               /* edge_id of edge in this vol */
     UT_hash_handle hh;         /* makes this structure hashable */
-};
-
-struct edge *edgetable = NULL;
-
-void add_edge(int edge_key, int vol_id, int edge_id) {
-    struct edge *s;
-
-    s = (struct edge*)malloc(sizeof(struct edge));
-    s->key = edge_key;
+} edge_t;
+
+edge_t *edgetable = NULL;
+
+void add_edge(edge_key_t key, int vol_id, int edge_id) {
+    edge_t *s;
+
+    s = (edge_t*) malloc(sizeof(edge_t));
+    memset(s, 0, sizeof(edge_t));
+    s->key.i = key.i;
+    s->key.j = key.j;
     s->vol_id = vol_id;
     s->edge_id = edge_id;
-    HASH_ADD_INT( edgetable, key, s );  /* key: name of key field */
-}
-
-struct edge *find_edge(int edge_key) {
-    struct edge *s;
-
-    HASH_FIND_INT( edgetable, &edge_key, s );  /* s: output pointer */
+    HASH_ADD(hh, edgetable, key, sizeof(edge_key_t), s);  /* key: name of key field */
+}
+
+edge_t *find_edge(edge_key_t key) {
+    edge_t *s;
+
+    HASH_FIND(hh, edgetable, &key, sizeof(edge_key_t), s);  /* s: output pointer */
     return s;
 }
 
-void delete_edge(struct edge *edge) {
+void delete_edge(edge_t *edge) {
     HASH_DEL( edgetable, edge);  /* user: pointer to deletee */
     free(edge);
@@ -52,8 +59,8 @@
 
 void delete_all() {
-  struct edge *current_edge, *tmp;
+  edge_t *current_edge, *tmp;
 
   HASH_ITER(hh, edgetable, current_edge, tmp) {
-    HASH_DEL(edgetable,current_edge);  /* delete it (edgetable advances to next) */
+    HASH_DEL(edgetable, current_edge);  /* delete it (edgetable advances to next) */
     free(current_edge);            /* free it */
   } 
@@ -61,17 +68,18 @@
 
 void print_edges() {
-    struct edge *s;
-
-    for(s=edgetable; s != NULL; s=(struct edge*)(s->hh.next)) {
-        printf("edge key %d: vol_id %d  edge_id %d\n", s->key, s->vol_id, s->edge_id);
+    edge_t *s;
+
+    for(s=edgetable; s != NULL; s=(edge_t*)(s->hh.next)) {
+        printf("edge key i %d i %d vol_id %d  edge_id %d\n",
+                      s->key.i, s->key.j, s->vol_id, s->edge_id);
     }
 }
 
-int vol_id_sort(struct edge *a, struct edge *b) {
+int vol_id_sort(edge_t *a, edge_t *b) {
     return (a->vol_id - b->vol_id);
 }
 
-int key_sort(struct edge *a, struct edge *b) {
-    return (a->key - b->key);
+int key_sort(edge_t *a, edge_t *b) {
+    return (a->key.i - b->key.i);
 }
 
@@ -88,16 +96,18 @@
 // Code to calculate neighbour structure
 //==============================================================================
-int _create_neighbours(int N,
+int _build_neighbour_structure(int N, int M,
+                      long* triangles,
 		      long* neighbours,
                       long* neighbour_edges,
-                      long* number_of_boundaries,
-		      long* triangles) {
+                      long* number_of_boundaries)
+		      {
     int k;
     int k3;
     int n0,n1,n2;
-    int key;
     int vol_id;
     int edge_id;
-    struct edge *s;
+    int err = 0;
+    edge_t *s;
+    edge_key_t key;
 
     //--------------------------------------------------------------------------
@@ -106,5 +116,5 @@
     // two nodes defining the edge
     //--------------------------------------------------------------------------
-    for (k=0; k<N; k++) {
+    for (k=0; k<M; k++) {
 
         // Run through triangles
@@ -117,26 +127,72 @@
         // Add edges
 
+        //----------------------------------------------------------------------
         // edge 0, n1 - n2
-        key = n1*N + n2;
+        //----------------------------------------------------------------------
+        key.i = n1;
+        key.j = n2;
         vol_id = k;
         edge_id = 0;
-
+        
+        // Error if duplicates
+        s = find_edge(key);
+        if (s) {
+            err = 1;
+            break;
+        }
+        // Otherwise add edge
         add_edge(key, vol_id, edge_id);
 
+        //----------------------------------------------------------------------
         // edge 1, n2 - n0
-        key = n2*N + n0;
+        //----------------------------------------------------------------------
+        key.i = n2;
+        key.j = n0;
         vol_id = k;
         edge_id = 1;
 
+        // Error if duplicates
+        s = find_edge(key);
+        if (s) {
+            err = 1;
+            break;
+        }
+        // Otherwise add edge
         add_edge(key, vol_id, edge_id);
 
+        //----------------------------------------------------------------------
         // edge 2, n0 - n1
-        key = n0*N + n1;
+        //----------------------------------------------------------------------
+        key.i = n0;
+        key.j = n1;
         vol_id = k;
         edge_id = 2;
 
+        // Error if duplicates
+        s = find_edge(key);
+        if (s) {
+            err = 1;
+            break;
+        }
+        // Otherwise add edge
         add_edge(key, vol_id, edge_id);
 
     }
+
+    
+    //--------------------------------------------------------------------------
+    // return with an error code if duplicate key found
+    // Clean up hashtable
+    //--------------------------------------------------------------------------
+    if (err) {
+        //printf("Duplicate Keys:\n");
+        //printf("key.i %d key.j %d vol_id %d edge_id %d \n",
+        //       s->key.i, s->key.j,s->vol_id,s->edge_id);
+        //printf("key.i %d key.j %d vol_id %d edge_id %d \n",
+        //       key.i,key.j,vol_id,edge_id);
+        delete_all();
+        return err;
+    }
+
 
     //--------------------------------------------------------------------------
@@ -145,5 +201,5 @@
     //reverse direction of segments and lookup neighbours.
     //--------------------------------------------------------------------------
-    for (k=0; k<N; k++) {
+    for (k=0; k<M; k++) {
 
         // Run through triangles
@@ -159,28 +215,31 @@
 
         // edge 0, n1 - n2
-        key = n2*N + n1;
+        key.i = n2;
+        key.j = n1;
+        s = find_edge(key);
+        if (s) {
+            neighbours[k3]      = s -> vol_id;
+            neighbour_edges[k3] = s -> edge_id;
+            number_of_boundaries[k] -= 1;
+        }
+
+        // edge 1, n2 - n0
+        key.i = n0;
+        key.j = n2;
+        s = find_edge(key);
+        if (s) {
+            neighbours[k3+1]      = s -> vol_id;
+            neighbour_edges[k3+1] = s -> edge_id;
+            number_of_boundaries[k] -= 1;
+        }
+
+        // edge 2, n0 - n1
+        key.i = n1;
+        key.j = n0;
         s = find_edge(key);
         if (s) {
             neighbours[k3+2]      = s -> vol_id;
             neighbour_edges[k3+2] = s -> edge_id;
-            number_of_boundaries[k3+2] -= 1;
-        }
-
-        // edge 1, n2 - n0
-        key = n0*N + n2;
-        s = find_edge(key);
-        if (s) {
-            neighbours[k3+2]      = s -> vol_id;
-            neighbour_edges[k3+2] = s -> edge_id;
-            number_of_boundaries[k3+2] -= 1;
-        }
-
-        // edge 2, n0 - n1
-        key = n1*N + n0;
-        s = find_edge(key);
-        if (s) {
-            neighbours[k3+2]      = s -> vol_id;
-            neighbour_edges[k3+2] = s -> edge_id;
-            number_of_boundaries[k3+2] -= 1;
+            number_of_boundaries[k] -= 1;
         }
 
@@ -189,5 +248,5 @@
     delete_all();  /* free any structures */
 
-    return 0;
+    return err;
 
 }
@@ -198,8 +257,14 @@
 //==============================================================================
 
-PyObject *create_neighbours(PyObject *self, PyObject *args) {
+PyObject *build_neighbour_structure(PyObject *self, PyObject *args) {
 
   /*
    * Update neighbours array using triangles array
+   *
+   * N is number of nodes (vertices)
+   * triangle nodes defining triangles
+   * neighbour across edge_id
+   * neighbour_edges edge_id of edge in neighbouring triangle
+   * number_of_boundaries
   */
 
@@ -207,12 +272,16 @@
         PyArrayObject *triangles;
 
-	int N, err;
+	int N; // Number of nodes (read in)
+        int M; // Number of triangles (calculated from triangle array)
+        int err;
 
 
 	// Convert Python arguments to C
-	if (!PyArg_ParseTuple(args, "OOOO", &neighbours,
+	if (!PyArg_ParseTuple(args, "iOOOO", &N,
+                                            &triangles,
+                                            &neighbours,
                                             &neighbour_edges,
-                                            &number_of_boundaries,
-                                            &triangles)) {
+                                            &number_of_boundaries
+                                            )) {
 	  PyErr_SetString(PyExc_RuntimeError,
 			  "hashtable.c: create_neighbours could not parse input");
@@ -220,29 +289,31 @@
 	}
 
+        CHECK_C_CONTIG(triangles);
         CHECK_C_CONTIG(neighbours);
         CHECK_C_CONTIG(neighbour_edges);
         CHECK_C_CONTIG(number_of_boundaries);
-	CHECK_C_CONTIG(triangles);
-
-	N = triangles -> dimensions[0];
-
-	err = _create_neighbours(N,
+
+
+        M = triangles -> dimensions[0];
+
+
+	err = _build_neighbour_structure(N, M,
+                      (long*) triangles  -> data,
 		      (long*) neighbours -> data,
                       (long*) neighbour_edges -> data,
-                      (long*) number_of_boundaries -> data,
-		      (long*) triangles  -> data);
+                      (long*) number_of_boundaries -> data);
 
 
 	if (err != 0) {
 	  PyErr_SetString(PyExc_RuntimeError,
-			  "hashtable.c: error creating neighbours");
+			  "Duplicate Edge");
 	  return NULL;
 	}
 
 	// Release and return
-	Py_DECREF(triangles);
-	Py_DECREF(neighbours);
-        Py_DECREF(neighbour_edges);
-        Py_DECREF(number_of_boundaries);
+	//Py_DECREF(triangles);
+	//Py_DECREF(neighbours);
+        //Py_DECREF(neighbour_edges);
+        //Py_DECREF(number_of_boundaries);
 
 	return Py_BuildValue("");
@@ -256,5 +327,5 @@
 // Method table for python module
 static struct PyMethodDef MethodTable[] = {
-	{"create_neighbours", create_neighbours, METH_VARARGS, "Print out"},
+	{"build_neighbour_structure", build_neighbour_structure, METH_VARARGS, "Print out"},
 	{NULL, NULL, 0, NULL}   // sentinel
 };
Index: /trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/neighbour_mesh.py
===================================================================
--- /trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/neighbour_mesh.py	(revision 8503)
+++ /trunk/anuga_core/source/anuga/abstract_2d_finite_volumes/neighbour_mesh.py	(revision 8504)
@@ -233,5 +233,5 @@
 
 
-    def build_neighbour_structure(self):
+    def build_neighbour_structure_python(self):
         """Update all registered triangles to point to their neighbours.
 
@@ -256,13 +256,13 @@
             b = self.triangles[i, 1]
             c = self.triangles[i, 2]
-#            if neighbourdict.has_key((a,b)):
-#                    msg = "Edge 2 of triangle %d is duplicating edge %d of triangle %d.\n" %(i,neighbourdict[a,b][1],neighbourdict[a,b][0])
-#                    raise Exception(msg)
-#            if neighbourdict.has_key((b,c)):
-#                    msg = "Edge 0 of triangle %d is duplicating edge %d of triangle %d.\n" %(i,neighbourdict[b,c][1],neighbourdict[b,c][0])
-#                    raise Exception(msg)
-#            if neighbourdict.has_key((c,a)):
-#                    msg = "Edge 1 of triangle %d is duplicating edge %d of triangle %d.\n" %(i,neighbourdict[c,a][1],neighbourdict[c,a][0])
-#                    raise Exception(msg)
+            if neighbourdict.has_key((a,b)):
+                    msg = "Edge 2 of triangle %d is duplicating edge %d of triangle %d.\n" %(i,neighbourdict[a,b][1],neighbourdict[a,b][0])
+                    raise Exception(msg)
+            if neighbourdict.has_key((b,c)):
+                    msg = "Edge 0 of triangle %d is duplicating edge %d of triangle %d.\n" %(i,neighbourdict[b,c][1],neighbourdict[b,c][0])
+                    raise Exception(msg)
+            if neighbourdict.has_key((c,a)):
+                    msg = "Edge 1 of triangle %d is duplicating edge %d of triangle %d.\n" %(i,neighbourdict[c,a][1],neighbourdict[c,a][0])
+                    raise Exception(msg)
 
             neighbourdict[a,b] = (i, 2) #(id, edge)
@@ -295,4 +295,25 @@
                 self.number_of_boundaries[i] -= 1
 
+    def build_neighbour_structure(self):
+        """Update all registered triangles to point to their neighbours.
+
+        Also, keep a tally of the number of boundaries for each triangle
+
+        Postconditions:
+          neighbours and neighbour_edges is populated
+          number_of_boundaries integer array is defined.
+        """
+
+        import hashtable
+        
+        N = self.number_of_nodes
+
+        
+        hashtable.build_neighbour_structure(N,
+                                            self.triangles,
+                                            self.neighbours,
+                                            self.neighbour_edges,
+                                            self.number_of_boundaries)
+ 
 
     def build_surrogate_neighbour_structure(self):
@@ -312,7 +333,7 @@
 
         N = len(self) #Number of triangles
-        for i in range(N):
+        for i in xrange(N):
             #Find all neighbouring volumes that are not boundaries
-            for k in range(3):
+            for k in xrange(3):
                 if self.neighbours[i, k] < 0:
                     self.surrogate_neighbours[i, k] = i #Point this triangle
@@ -336,6 +357,6 @@
         if boundary is None:
             boundary = {}
-            for vol_id in range(len(self)):
-                for edge_id in range(0, 3):
+            for vol_id in xrange(len(self)):
+                for edge_id in xrange(0, 3):
                     if self.neighbours[vol_id, edge_id] < 0:
                         boundary[(vol_id, edge_id)] = default_boundary_tag
@@ -352,6 +373,6 @@
 
             #Check that all boundary segments are assigned a tag
-            for vol_id in range(len(self)):
-                for edge_id in range(0, 3):
+            for vol_id in xrange(len(self)):
+                for edge_id in xrange(0, 3):
                     if self.neighbours[vol_id, edge_id] < 0:
                         if not boundary.has_key( (vol_id, edge_id) ):
