Index: /anuga_core/source/anuga/utilities/log_test.py
===================================================================
--- /anuga_core/source/anuga/utilities/log_test.py	(revision 6901)
+++ /anuga_core/source/anuga/utilities/log_test.py	(revision 6902)
@@ -31,5 +31,4 @@
         if os.path.exists(STDOUT_LOG_NAME):
             os.remove(STDOUT_LOG_NAME)
-        pass
 
     ##
Index: /branches/numpy/anuga/abstract_2d_finite_volumes/domain.py
===================================================================
--- /branches/numpy/anuga/abstract_2d_finite_volumes/domain.py	(revision 6901)
+++ /branches/numpy/anuga/abstract_2d_finite_volumes/domain.py	(revision 6902)
@@ -92,4 +92,7 @@
         """
 
+        number_of_full_nodes=None
+        number_of_full_triangles=None
+        
         # Determine whether source is a mesh filename or coordinates
         if type(source) == types.StringType:
@@ -117,4 +120,5 @@
 
         # Expose Mesh attributes (FIXME: Maybe turn into methods)
+        self.triangles = self.mesh.triangles        
         self.centroid_coordinates = self.mesh.centroid_coordinates
         self.vertex_coordinates = self.mesh.vertex_coordinates
@@ -205,6 +209,7 @@
         # the ghost triangles.
         if not num.allclose(self.tri_full_flag[:self.number_of_full_nodes], 1):
-            print ('WARNING:  '
-                   'Not all full triangles are store before ghost triangles')
+            if self.numproc>1:
+                print ('WARNING:  '
+                       'Not all full triangles are store before ghost triangles')
 
         # Defaults
@@ -306,4 +311,6 @@
     def get_normal(self, *args, **kwargs):
         return self.mesh.get_normal(*args, **kwargs)
+    def get_triangle_containing_point(self, *args, **kwargs):
+        return self.mesh.get_triangle_containing_point(*args, **kwargs)
 
     def get_intersecting_segments(self, *args, **kwargs):
@@ -1745,8 +1752,28 @@
 
     ##
-    # @brief ??
+    # @brief Sequential update of ghost cells 
     def update_ghosts(self):
-        pass
-
+        # We must send the information from the full cells and
+        # receive the information for the ghost cells
+        # We have a list with ghosts expecting updates
+
+        from Numeric import take,put
+
+
+        #Update of ghost cells
+        iproc = self.processor
+        if self.full_send_dict.has_key(iproc):
+
+            # now store full as local id, global id, value
+            Idf  = self.full_send_dict[iproc][0]
+
+            # now store ghost as local id, global id, value
+            Idg = self.ghost_recv_dict[iproc][0]
+
+            for i, q in enumerate(self.conserved_quantities):
+                Q_cv =  self.quantities[q].centroid_values
+                put(Q_cv,     Idg, take(Q_cv,     Idf))
+
+ 
     ##
     # @brief Extrapolate conserved quantities from centroid to vertices
Index: /branches/numpy/anuga/abstract_2d_finite_volumes/generic_boundary_conditions.py
===================================================================
--- /branches/numpy/anuga/abstract_2d_finite_volumes/generic_boundary_conditions.py	(revision 6901)
+++ /branches/numpy/anuga/abstract_2d_finite_volumes/generic_boundary_conditions.py	(revision 6902)
@@ -82,6 +82,15 @@
     """Time dependent boundary returns values for the
     conserved quantities as a function of time.
-    Must specify domain to get access to model time and a function f(t)
-    which must return conserved quantities as a function time
+    Must specify domain to get access to model time and a function of t
+    which must return conserved quantities as a function time.
+    
+    Example:
+      B = Time_boundary(domain, 
+                        function=lambda t: [(60<t<3660)*2, 0, 0])
+      
+      This will produce a boundary condition with is a 2m high square wave
+      starting 60 seconds into the simulation and lasting one hour.
+      Momentum applied will be 0 at all times.
+                        
     """
 
@@ -98,4 +107,16 @@
         self.verbose = verbose
 
+        
+        # FIXME: Temporary code to deal with both f and function
+        if function is not None and f is not None:
+            raise Exception, 'Specify either function or f to Time_boundary'
+            
+        if function is None and f is None:
+            raise Exception, 'You must specify a function to Time_boundary'
+            
+        if f is None:
+            f = function
+        #####
+        
         try:
             q = f(0.0)
Index: /branches/numpy/anuga/abstract_2d_finite_volumes/mesh_factory.py
===================================================================
--- /branches/numpy/anuga/abstract_2d_finite_volumes/mesh_factory.py	(revision 6901)
+++ /branches/numpy/anuga/abstract_2d_finite_volumes/mesh_factory.py	(revision 6902)
@@ -201,4 +201,151 @@
 
     return points, elements, boundary
+
+
+def rectangular_periodic(m_g, n_g, len1_g=1.0, len2_g=1.0, origin_g = (0.0, 0.0)):
+
+
+    """Setup a rectangular grid of triangles
+    with m+1 by n+1 grid points
+    and side lengths len1, len2. If side lengths are omitted
+    the mesh defaults to the unit square, divided between all the
+    processors
+
+    len1: x direction (left to right)
+    len2: y direction (bottom to top)
+
+    """
+
+    processor = 0
+    numproc   = 1
+
+    
+    n = n_g
+    m_low  = -1
+    m_high = m_g +1
+
+    m = m_high - m_low
+
+    delta1 = float(len1_g)/m_g
+    delta2 = float(len2_g)/n_g
+
+    len1 = len1_g*float(m)/float(m_g)
+    len2 = len2_g
+    origin = ( origin_g[0]+float(m_low)/float(m_g)*len1_g, origin_g[1] )
+
+    #Calculate number of points
+    Np = (m+1)*(n+1)
+
+    class VIndex:
+
+        def __init__(self, n,m):
+            self.n = n
+            self.m = m
+
+        def __call__(self, i,j):
+            return j+i*(self.n+1)
+
+    class EIndex:
+
+        def __init__(self, n,m):
+            self.n = n
+            self.m = m
+
+        def __call__(self, i,j):
+            return 2*(j+i*self.n)
+
+
+    I = VIndex(n,m)
+    E = EIndex(n,m)
+
+    points = num.zeros( (Np,2), num.Float)
+
+    for i in range(m+1):
+        for j in range(n+1):
+
+            points[I(i,j),:] = [i*delta1 + origin[0], j*delta2 + origin[1]]
+
+    #Construct 2 triangles per rectangular element and assign tags to boundary
+    #Calculate number of triangles
+    Nt = 2*m*n
+
+
+    elements = num.zeros( (Nt,3), num.Int)
+    boundary = {}
+    Idgl = []
+    Idfl = []
+    Idgr = []
+    Idfr = []
+
+    full_send_dict = {}
+    ghost_recv_dict = {}
+    nt = -1
+    for i in range(m):
+        for j in range(n):
+
+            i1 = I(i,j+1)
+            i2 = I(i,j)
+            i3 = I(i+1,j+1)
+            i4 = I(i+1,j)
+
+            #Lower Element
+            nt = E(i,j)
+            if i == 0:
+                Idgl.append(nt)
+
+            if i == 1:
+                Idfl.append(nt)
+
+            if i == m-2:
+                Idfr.append(nt)
+
+            if i == m-1:
+                Idgr.append(nt)
+
+            if i == m-1:
+                if processor == numproc-1:
+                    boundary[nt, 2] = 'right'
+                else:
+                    boundary[nt, 2] = 'ghost'
+        
+            if j == 0:
+                boundary[nt, 1] = 'bottom'
+            elements[nt,:] = [i4,i3,i2]
+
+            #Upper Element
+            nt = E(i,j)+1
+            if i == 0:
+                Idgl.append(nt)
+
+            if i == 1:
+                Idfl.append(nt)
+
+            if i == m-2:
+                Idfr.append(nt)
+
+            if i == m-1:
+                Idgr.append(nt)
+
+            if i == 0:
+                if processor == 0:
+                    boundary[nt, 2] = 'left'
+                else:
+                    boundary[nt, 2] = 'ghost'
+            if j == n-1:
+                boundary[nt, 1] = 'top'
+            elements[nt,:] = [i1,i2,i3]
+
+    Idfl.extend(Idfr)
+    Idgr.extend(Idgl)
+
+    Idfl = num.array(Idfl, num.Int)
+    Idgr = num.array(Idgr, num.Int)
+    
+    full_send_dict[processor]  = [Idfl, Idfl]
+    ghost_recv_dict[processor] = [Idgr, Idgr]
+
+
+    return  points, elements, boundary, full_send_dict, ghost_recv_dict
+
 
 def oblique(m, n, lenx = 1.0, leny = 1.0, theta = 8.95, origin = (0.0, 0.0)):
Index: /branches/numpy/anuga/abstract_2d_finite_volumes/quantity.py
===================================================================
--- /branches/numpy/anuga/abstract_2d_finite_volumes/quantity.py	(revision 6901)
+++ /branches/numpy/anuga/abstract_2d_finite_volumes/quantity.py	(revision 6902)
@@ -1178,4 +1178,5 @@
         # Edges have already been deprecated in set_values, see changeset:5521,
         # but *might* be useful in get_values. Any thoughts anyone?
+        # YES (Ole): Edge values are necessary for volumetric balance check
 
         if location not in ['vertices', 'centroids',
Index: /branches/numpy/anuga/abstract_2d_finite_volumes/test_domain.py
===================================================================
--- /branches/numpy/anuga/abstract_2d_finite_volumes/test_domain.py	(revision 6901)
+++ /branches/numpy/anuga/abstract_2d_finite_volumes/test_domain.py	(revision 6902)
@@ -397,5 +397,5 @@
                                       
     def test_setting_timestepping_method(self):
-        """test_set_quanitities_to_be_monitored
+        """test_setting_timestepping_method
         """
 
@@ -803,4 +803,72 @@
                              [ 11.0,  11.0,  11.0]])
                              
+    def test_rectangular_periodic_and_ghosts(self):
+
+        from mesh_factory import rectangular_periodic
+        
+
+        M=5
+        N=2
+        points, vertices, boundary, full_send_dict, ghost_recv_dict = rectangular_periodic(M, N)
+
+        assert num.allclose(ghost_recv_dict[0][0], [24, 25, 26, 27,  0,  1,  2,  3])
+        assert num.allclose(full_send_dict[0][0] , [ 4,  5,  6,  7, 20, 21, 22, 23])
+
+        #print 'HERE'
+        
+        conserved_quantities = ['quant1', 'quant2']
+        domain = Domain(points, vertices, boundary, conserved_quantities,
+                        full_send_dict=full_send_dict,
+                        ghost_recv_dict=ghost_recv_dict)
+
+
+
+
+        assert num.allclose(ghost_recv_dict[0][0], [24, 25, 26, 27,  0,  1,  2,  3])
+        assert num.allclose(full_send_dict[0][0] , [ 4,  5,  6,  7, 20, 21, 22, 23])
+
+        def xylocation(x,y):
+            return 15*x + 9*y
+
+        
+        domain.set_quantity('quant1',xylocation,location='centroids')
+        domain.set_quantity('quant2',xylocation,location='centroids')
+
+
+        assert num.allclose(domain.quantities['quant1'].centroid_values,
+                            [  0.5,   1.,   5.,    5.5,   3.5,   4.,    8.,    8.5,   6.5,  7.,   11.,   11.5,   9.5,
+                               10.,   14.,   14.5,  12.5,  13.,   17.,   17.5,  15.5,  16.,   20.,   20.5,
+                               18.5,  19.,   23.,   23.5])
+
+
+
+        assert num.allclose(domain.quantities['quant2'].centroid_values,
+                            [  0.5,   1.,   5.,    5.5,   3.5,   4.,    8.,    8.5,   6.5,  7.,   11.,   11.5,   9.5,
+                               10.,   14.,   14.5,  12.5,  13.,   17.,   17.5,  15.5,  16.,   20.,   20.5,
+                               18.5,  19.,   23.,   23.5])
+
+        domain.update_ghosts()
+
+
+        assert num.allclose(domain.quantities['quant1'].centroid_values,
+                            [  15.5,  16.,   20.,   20.5,   3.5,   4.,    8.,    8.5,   6.5,  7.,   11.,   11.5,   9.5,
+                               10.,   14.,   14.5,  12.5,  13.,   17.,   17.5,  15.5,  16.,   20.,   20.5,
+                                3.5,   4.,    8.,    8.5])
+
+
+
+        assert num.allclose(domain.quantities['quant2'].centroid_values,
+                            [  15.5,  16.,   20.,   20.5,   3.5,   4.,    8.,    8.5,   6.5,  7.,   11.,   11.5,   9.5,
+                               10.,   14.,   14.5,  12.5,  13.,   17.,   17.5,  15.5,  16.,   20.,   20.5,
+                                3.5,   4.,    8.,    8.5])
+
+        
+        assert num.allclose(domain.tri_full_flag, [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+                                                   1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0])
+
+        #Test that points are arranged in a counter clock wise order
+        domain.check_integrity()
+
+
     def test_that_mesh_methods_exist(self):
         """test_that_mesh_methods_exist
@@ -828,4 +896,5 @@
         domain.get_number_of_nodes()
         domain.get_normal(0,0)
+        domain.get_triangle_containing_point([0.4,0.5])
         domain.get_intersecting_segments([[0.0, 0.0], [0.0, 1.0]])
         domain.get_disconnected_triangles()
Index: /branches/numpy/anuga/coordinate_transforms/redfearn.py
===================================================================
--- /branches/numpy/anuga/coordinate_transforms/redfearn.py	(revision 6901)
+++ /branches/numpy/anuga/coordinate_transforms/redfearn.py	(revision 6902)
@@ -48,4 +48,5 @@
     If zone is specified reproject lat and long to specified zone instead of
     standard zone
+
     If meridian is specified, reproject lat and lon to that instead of zone. In this case
     zone will be set to -1 to indicate non-UTM projection
Index: /branches/numpy/anuga/culvert_flows/culvert_class.py
===================================================================
--- /branches/numpy/anuga/culvert_flows/culvert_class.py	(revision 6901)
+++ /branches/numpy/anuga/culvert_flows/culvert_class.py	(revision 6902)
@@ -325,5 +325,4 @@
             if time - self.last_update > self.update_interval or time == 0.0:
                 update = True
-
             
         if self.log_filename is not None:        
Index: /branches/numpy/anuga/culvert_flows/culvert_routines.py
===================================================================
--- /branches/numpy/anuga/culvert_flows/culvert_routines.py	(revision 6901)
+++ /branches/numpy/anuga/culvert_flows/culvert_routines.py	(revision 6902)
@@ -217,4 +217,5 @@
     else: # inlet_depth < 0.01:
         Q = barrel_velocity = outlet_culvert_depth = 0.0
+
     # Temporary flow limit
     if barrel_velocity > max_velocity:
Index: /branches/numpy/anuga/culvert_flows/test_culvert_routines.py
===================================================================
--- /branches/numpy/anuga/culvert_flows/test_culvert_routines.py	(revision 6901)
+++ /branches/numpy/anuga/culvert_flows/test_culvert_routines.py	(revision 6902)
@@ -19,11 +19,11 @@
 
 
-    def test_boyd_1(self):
-        """test_boyd_1
-        
-        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
-        """
-        # FIXME(Ole): This test fails (20 Feb 2009)
-
+    def test_boyd_0(self):
+        """test_boyd_0
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski
+        This test is the only one that passed in late February 2009
+        """
+      
         g=9.81
         culvert_slope=0.1  # Downward
@@ -67,6 +67,6 @@
         
 
-    def test_boyd_2(self):
-        """test_boyd_2
+    def Xtest_boyd_00(self):
+        """test_boyd_00
         
         This tests the Boyd routine with data obtained from ??? by Petar Milevski    
@@ -108,8 +108,461 @@
         
         #print Q, v, d
-        #assert num.allclose(Q, 0.185, rtol=1.0e-3)
+        assert num.allclose(Q, 0.185, rtol=1.0e-3)
         #assert num.allclose(v, 0.93)
         #assert num.allclose(d, 0.0)
         
+    def Xtest_boyd_1(self):
+        """test_boyd_1
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.01  # Downward
+
+        inlet_depth=0.263
+        outlet_depth=0.0
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 1.13, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.15, rtol=1.0e-2) #depth at outlet used to calc v 
+        
+    def Xtest_boyd_2(self):
+        """test_boyd_2
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.01  # Downward
+
+        inlet_depth=1.135
+        outlet_depth=0.0
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 2.59, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.563, rtol=1.0e-2) #depth at outlet used to calc v  
+
+    def Xtest_boyd_3(self):
+        """test_boyd_3
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.01  # Downward
+
+        inlet_depth=12.747
+        outlet_depth=0.0
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 5.00, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 11.022, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.72, rtol=1.0e-2) #depth at outlet used to calc v
+
+    def Xtest_boyd_4(self):
+        """test_boyd_4
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.01  # Downward
+
+        inlet_depth=1.004
+        outlet_depth=1.00
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 0.22, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v
+
+    def Xtest_boyd_5(self):
+        """test_boyd_5
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.01  # Downward
+
+        inlet_depth=1.401
+        outlet_depth=1.00
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 2.204, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v
+
+
+    def Xtest_boyd_6(self):
+        """test_boyd_5
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.01  # Downward
+
+        inlet_depth=12.747
+        outlet_depth=1.00
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 5.00, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 11.022, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v
+
+
+    def Xtest_boyd_7(self):
+        """test_boyd_7
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.1  # Downward
+
+        inlet_depth=0.303
+        outlet_depth=0.00
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 1.13, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.19, rtol=1.0e-2) #depth at outlet used to calc v
+
+
+    def Xtest_boyd_8(self):
+        """test_boyd_8
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.1  # Downward
+
+        inlet_depth=1.135
+        outlet_depth=0.00
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 2.204, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v
+
+    def Xtest_boyd_9(self):
+        """test_boyd_9
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.1  # Downward
+
+        inlet_depth=1.1504
+        outlet_depth=1.5
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 0.10, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 0.22, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v
+
+
+    def Xtest_boyd_10(self):
+        """test_boyd_9
+        
+        This tests the Boyd routine with data obtained from ??? by Petar Milevski    
+        """
+        # FIXME(Ole): This test fails (20 Feb 2009)
+
+        g=9.81
+        culvert_slope=0.1  # Downward
+
+        inlet_depth=1.901
+        outlet_depth=1.5
+
+        culvert_length=4.0
+        culvert_width=0.75
+        culvert_height=0.75
+        
+        culvert_type='pipe'
+        manning=0.013
+        sum_loss=1.5
+
+        inlet_specific_energy=inlet_depth #+0.5*v**2/g 
+        z_in = 0.0
+        z_out = -culvert_length*culvert_slope/100
+        E_in = z_in+inlet_depth  #+ 0.5*v**2/g
+        E_out = z_out+outlet_depth  #+ 0.5*v**2/g
+        delta_total_energy = E_in-E_out
+
+        Q, v, d = boyd_generalised_culvert_model(inlet_depth, 
+                                                 outlet_depth,
+                                                 inlet_specific_energy, 
+                                                 delta_total_energy, 
+                                                 g,
+                                                 culvert_length,
+                                                 culvert_width,
+                                                 culvert_height,
+                                                 culvert_type,
+                                                 manning,
+                                                 sum_loss)
+        
+        print Q, v, d
+        assert num.allclose(Q, 1.00, rtol=1.0e-2) #inflow
+        assert num.allclose(v, 2.204, rtol=1.0e-2) #outflow velocity
+        assert num.allclose(d, 0.76, rtol=1.0e-2) #depth at outlet used to calc v
     
                
Index: /branches/numpy/anuga/geospatial_data/geospatial_data.py
===================================================================
--- /branches/numpy/anuga/geospatial_data/geospatial_data.py	(revision 6901)
+++ /branches/numpy/anuga/geospatial_data/geospatial_data.py	(revision 6902)
@@ -862,7 +862,7 @@
                  self.file_pointer) = _read_csv_file_blocking(self.file_pointer,
                                                               self.header[:],
-                                                              max_read_lines= \
+                                                              max_read_lines=
                                                            self.max_read_lines,
-                                                              verbose= \
+                                                              verbose=
                                                                   self.verbose)
 
Index: /branches/numpy/anuga/load_mesh/loadASCII.py
===================================================================
--- /branches/numpy/anuga/load_mesh/loadASCII.py	(revision 6901)
+++ /branches/numpy/anuga/load_mesh/loadASCII.py	(revision 6902)
@@ -817,5 +817,5 @@
         mesh['vertex_attributes'] = None
 
-    mesh['vertex_attribute_titles'] = []
+#    mesh['vertex_attribute_titles'] = []
     try:
         titles = fid.variables['vertex_attribute_titles'][:]
@@ -829,5 +829,5 @@
         mesh['segments'] = num.array([], num.int)      #array default#
 
-    mesh['segment_tags'] = []
+#    mesh['segment_tags'] = []
     try:
         tags = fid.variables['segment_tags'][:]
@@ -844,5 +844,5 @@
         mesh['triangle_neighbors'] = num.array([], num.int)     #array default#
 
-    mesh['triangle_tags'] = []
+#    mesh['triangle_tags'] = []
     try:
         tags = fid.variables['triangle_tags'][:]
Index: /branches/numpy/anuga/load_mesh/test_loadASCII.py
===================================================================
--- /branches/numpy/anuga/load_mesh/test_loadASCII.py	(revision 6901)
+++ /branches/numpy/anuga/load_mesh/test_loadASCII.py	(revision 6902)
@@ -410,6 +410,7 @@
         self.failUnless(num.alltrue(loaded_dict['vertex_attributes'] ==
                                     dict['vertex_attributes']) or
-                        (loaded_dict['vertex_attributes'] == None and
-                         dict['vertex_attributes'] == []),
+                                    (loaded_dict['vertex_attributes'] ==
+                                    None and
+                                    dict['vertex_attributes'] == []),
                         fail_string + ' failed!! Test vertex_attributes')
 
@@ -423,6 +424,6 @@
             self.failUnless(seg == ldseg, fail_string + ' failed\n' + msg)
 
-        dict_array = num.array(dict['vertex_attribute_titles'])
-        loaded_dict_array = num.array(loaded_dict['vertex_attribute_titles'])
+#        dict_array = num.array(dict['vertex_attribute_titles'])
+#        loaded_dict_array = num.array(loaded_dict['vertex_attribute_titles'])
         try:
             assert num.allclose(dict_array, loaded_dict_array)
Index: /branches/numpy/anuga/shallow_water/data_manager.py
===================================================================
--- /branches/numpy/anuga/shallow_water/data_manager.py	(revision 6901)
+++ /branches/numpy/anuga/shallow_water/data_manager.py	(revision 6902)
@@ -3575,11 +3575,11 @@
     other_quantities.remove('z')
     other_quantities.remove('volumes')
-    #try:
-    #    other_quantities.remove('stage_range')
-    #    other_quantities.remove('xmomentum_range')
-    #    other_quantities.remove('ymomentum_range')
-    #    other_quantities.remove('elevation_range')
-    #except:
-    #    pass
+    try:
+        other_quantities.remove('stage_range')
+        other_quantities.remove('xmomentum_range')
+        other_quantities.remove('ymomentum_range')
+        other_quantities.remove('elevation_range')
+    except:
+        pass
 
     conserved_quantities.remove('time')
@@ -5338,5 +5338,5 @@
         j += 1
 
-    #if verbose: sww.verbose_quantities(outfile)
+    if verbose: sww.verbose_quantities(outfile)
 
     outfile.close()
@@ -5855,5 +5855,5 @@
     # @param smoothing True if smoothing is to be used.
     # @param order 
-    # @param sww_precision Data type of the quantitiy written (netcdf constant)
+    # @param sww_precision Data type of the quantity written (netcdf constant)
     # @param verbose True if this function is to be verbose.
     # @note If 'times' is a list, the info will be made relative.
@@ -5936,12 +5936,11 @@
                                ('number_of_points',))
         q = 'elevation'
-        #outfile.createVariable(q + Write_sww.RANGE, sww_precision,
-        #                       ('numbers_in_range',))
-
-
-        ## Initialise ranges with small and large sentinels.
-        ## If this was in pure Python we could have used None sensibly
-        #outfile.variables[q+Write_sww.RANGE][0] = max_float  # Min
-        #outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max
+        outfile.createVariable(q + Write_sww.RANGE, sww_precision,
+                               ('numbers_in_range',))
+
+        # Initialise ranges with small and large sentinels.
+        # If this was in pure Python we could have used None sensibly
+        outfile.variables[q+Write_sww.RANGE][0] = max_float  # Min
+        outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max
 
         # FIXME: Backwards compatibility
@@ -5958,11 +5957,11 @@
             outfile.createVariable(q, sww_precision, ('number_of_timesteps',
                                                       'number_of_points'))
-            #outfile.createVariable(q + Write_sww.RANGE, sww_precision,
-            #                       ('numbers_in_range',))
+            outfile.createVariable(q + Write_sww.RANGE, sww_precision,
+                                   ('numbers_in_range',))
 
             # Initialise ranges with small and large sentinels.
             # If this was in pure Python we could have used None sensibly
-            #outfile.variables[q+Write_sww.RANGE][0] = max_float  # Min
-            #outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max
+            outfile.variables[q+Write_sww.RANGE][0] = max_float  # Min
+            outfile.variables[q+Write_sww.RANGE][1] = -max_float # Max
 
         if isinstance(times, (list, num.ndarray)):
@@ -6073,6 +6072,6 @@
         q = 'elevation'
         # This updates the _range values
-        #outfile.variables[q + Write_sww.RANGE][0] = min(elevation)
-        #outfile.variables[q + Write_sww.RANGE][1] = max(elevation)
+        outfile.variables[q + Write_sww.RANGE][0] = num.min(elevation)
+        outfile.variables[q + Write_sww.RANGE][1] = num.max(elevation)
 
 
@@ -6126,24 +6125,24 @@
                                 q_values.astype(sww_precision)
         
-        #        # This updates the _range values
-        #        q_range = outfile.variables[q + Write_sww.RANGE][:]
-        #        q_values_min = min(q_values)
-        #        if q_values_min < q_range[0]:
-        #            outfile.variables[q + Write_sww.RANGE][0] = q_values_min
-        #        q_values_max = max(q_values)
-        #        if q_values_max > q_range[1]:
-        #            outfile.variables[q + Write_sww.RANGE][1] = q_values_max
+                # This updates the _range values
+                q_range = outfile.variables[q + Write_sww.RANGE][:]
+                q_values_min = num.min(q_values)
+                if q_values_min < q_range[0]:
+                    outfile.variables[q + Write_sww.RANGE][0] = q_values_min
+                q_values_max = num.max(q_values)
+                if q_values_max > q_range[1]:
+                    outfile.variables[q + Write_sww.RANGE][1] = q_values_max
 
     ##
     # @brief Print the quantities in the underlying file.
     # @param outfile UNUSED.
-    #def verbose_quantities(self, outfile):
-    #    print '------------------------------------------------'
-    #    print 'More Statistics:'
-    #    for q in Write_sww.sww_quantities:
-    #        print '  %s in [%f, %f]' % (q,
-    #                                    outfile.variables[q+Write_sww.RANGE][0],
-    #                                    outfile.variables[q+Write_sww.RANGE][1])
-    #    print '------------------------------------------------'
+    def verbose_quantities(self, outfile):
+        print '------------------------------------------------'
+        print 'More Statistics:'
+        for q in Write_sww.sww_quantities:
+            print '  %s in [%f, %f]' % (q,
+                                        outfile.variables[q+Write_sww.RANGE][0],
+                                        outfile.variables[q+Write_sww.RANGE][1])
+        print '------------------------------------------------'
 
 
@@ -6496,11 +6495,11 @@
 
                 # This updates the _range values
-                #q_range = outfile.variables[q + Write_sts.RANGE][:]
-                #q_values_min = min(q_values)
-                #if q_values_min < q_range[0]:
-                #    outfile.variables[q + Write_sts.RANGE][0] = q_values_min
-                #q_values_max = max(q_values)
-                #if q_values_max > q_range[1]:
-                #    outfile.variables[q + Write_sts.RANGE][1] = q_values_max
+                q_range = outfile.variables[q + Write_sts.RANGE][:]
+                q_values_min = num.min(q_values)
+                if q_values_min < q_range[0]:
+                    outfile.variables[q + Write_sts.RANGE][0] = q_values_min
+                q_values_max = num.max(q_values)
+                if q_values_max > q_range[1]:
+                    outfile.variables[q + Write_sts.RANGE][1] = q_values_max
 
 
@@ -6673,6 +6672,4 @@
 
 
-# FIXME (DSG): Add unit test, make general, not just 2 files,
-# but any number of files.
 ##
 # @brief Copy a file to a directory, and optionally append another file to it.
@@ -6680,21 +6677,39 @@
 # @param filename Path to file to copy to directory 'dir_name'.
 # @param filename2 Optional path to file to append to copied file.
-def copy_code_files(dir_name, filename1, filename2=None):
+# @param verbose True if this function is to be verbose.
+# @note Allow filenames to be either a string or sequence of strings.
+def copy_code_files(dir_name, filename1, filename2=None, verbose=False):
     """Copies "filename1" and "filename2" to "dir_name".
-    Very useful for information management
-    filename1 and filename2 are both absolute pathnames
-    """
-
+
+    Each 'filename' may be a string or list of filename strings.
+
+    Filenames must be absolute pathnames
+    """
+
+    ##
+    # @brief copies a file or sequence to destination directory.
+    # @param dest The destination directory to copy to.
+    # @param file A filename string or sequence of filename strings.
+    def copy_file_or_sequence(dest, file):
+        if hasattr(file, '__iter__'):
+            for f in file:
+                shutil.copy(f, dir_name)
+                if verbose:
+                    print 'File %s copied' % (f)
+        else:
+            shutil.copy(file, dir_name)
+            if verbose:
+                print 'File %s copied' % (file)
+
+    # check we have a destination directory, create if necessary
     if access(dir_name, F_OK) == 0:
-        print 'Make directory %s' % dir_name
-        mkdir (dir_name,0777)
-
-    shutil.copy(filename1, dir_name + sep + basename(filename1))
-
-    if filename2 != None:
-        shutil.copy(filename2, dir_name + sep + basename(filename2))
-        print 'Files %s and %s copied' %(filename1, filename2)
-    else:
-        print 'File %s copied' %(filename1)
+        if verbose:
+            print 'Make directory %s' % dir_name
+        mkdir(dir_name, 0777)
+
+    copy_file_or_sequence(dir_name, filename1)
+
+    if not filename2 is None:
+        copy_file_or_sequence(dir_name, filename2)
 
 
Index: /branches/numpy/anuga/shallow_water/shallow_water_ext.c
===================================================================
--- /branches/numpy/anuga/shallow_water/shallow_water_ext.c	(revision 6901)
+++ /branches/numpy/anuga/shallow_water/shallow_water_ext.c	(revision 6902)
@@ -28,4 +28,5 @@
 
 // Computational function for rotation
+// FIXME: Perhaps inline this and profile
 int _rotate(double *q, double n1, double n2) {
   /*Rotate the momentum component q (q[1], q[2])
@@ -52,5 +53,5 @@
 
 int find_qmin_and_qmax(double dq0, double dq1, double dq2, 
-		       double *qmin, double *qmax){
+               double *qmin, double *qmax){
   // Considering the centroid of an FV triangle and the vertices of its 
   // auxiliary triangle, find 
@@ -67,8 +68,8 @@
     if (dq1>=dq2){
       if (dq1>=0.0)
-	*qmax=dq0+dq1;
+    *qmax=dq0+dq1;
       else
-	*qmax=dq0;
-	
+    *qmax=dq0;
+    
       *qmin=dq0+dq2;
       if (*qmin>=0.0) *qmin = 0.0;
@@ -76,9 +77,9 @@
     else{// dq1<dq2
       if (dq2>0)
-	*qmax=dq0+dq2;
+    *qmax=dq0+dq2;
       else
-	*qmax=dq0;
-	
-      *qmin=dq0+dq1;	
+    *qmax=dq0;
+    
+      *qmin=dq0+dq1;    
       if (*qmin>=0.0) *qmin=0.0;
     }
@@ -87,17 +88,17 @@
     if (dq1<=dq2){
       if (dq1<0.0)
-	*qmin=dq0+dq1;
+    *qmin=dq0+dq1;
       else
-	*qmin=dq0;
-	
-      *qmax=dq0+dq2;	
+    *qmin=dq0;
+    
+      *qmax=dq0+dq2;    
       if (*qmax<=0.0) *qmax=0.0;
     }
     else{// dq1>dq2
       if (dq2<0.0)
-	*qmin=dq0+dq2;
+    *qmin=dq0+dq2;
       else
-	*qmin=dq0;
-	
+    *qmin=dq0;
+    
       *qmax=dq0+dq1;
       if (*qmax<=0.0) *qmax=0.0;
@@ -133,6 +134,8 @@
   
   phi=min(r*beta_w,1.0);
-  for (i=0;i<3;i++)
-    dqv[i]=dqv[i]*phi;
+  //for (i=0;i<3;i++)
+  dqv[0]=dqv[0]*phi;
+  dqv[1]=dqv[1]*phi;
+  dqv[2]=dqv[2]*phi;
     
   return 0;
@@ -141,8 +144,8 @@
 
 double compute_froude_number(double uh,
-			     double h, 
-			     double g,
-			     double epsilon) {
-			  
+                 double h, 
+                 double g,
+                 double epsilon) {
+              
   // Compute Froude number; v/sqrt(gh)
   // FIXME (Ole): Not currently in use
@@ -166,8 +169,10 @@
 // This is used by flux functions
 // Input parameters uh and h may be modified by this function.
+
+// FIXME: Perhaps inline this and profile
 double _compute_speed(double *uh, 
-		      double *h, 
-		      double epsilon, 
-		      double h0) {
+              double *h, 
+              double epsilon, 
+              double h0) {
   
   double u;
@@ -188,10 +193,67 @@
 }
 
+
+// Optimised squareroot computation
+//
+//See 
+//http://www.lomont.org/Math/Papers/2003/InvSqrt.pdf
+//and http://mail.opensolaris.org/pipermail/tools-gcc/2005-August/000047.html
+float fast_squareroot_approximation(float number) {
+  float x; 
+  const float f = 1.5;
+
+  // Allow i and y to occupy the same memory
+  union
+  {
+    long i;
+    float y;
+  } u;
+  
+  // Good initial guess  
+  x = number * 0.5;  
+  u.y  = number;
+  u.i  = 0x5f3759df - ( u.i >> 1 );
+  
+  // Take a few iterations
+  u.y  = u.y * ( f - ( x * u.y * u.y ) );
+  u.y  = u.y * ( f - ( x * u.y * u.y ) );
+    
+  return number * u.y;
+}
+
+
+
+// Optimised squareroot computation (double version, slower)
+double Xfast_squareroot_approximation(double number) {
+  double x;
+  const double f = 1.5;
+    
+  // Allow i and y to occupy the same memory    
+  union
+  {
+    long long i;
+    double y;
+  } u;
+
+  // Good initial guess
+  x = number * 0.5;
+  u.y  = number;
+  u.i  = 0x5fe6ec85e7de30daLL - ( u.i >> 1 );
+  
+  // Take a few iterations  
+  u.y  = u.y * ( f - ( x * u.y * u.y ) );
+  u.y  = u.y * ( f - ( x * u.y * u.y ) );
+
+  return number * u.y;
+}
+
+
 // Innermost flux function (using stage w=z+h)
 int _flux_function_central(double *q_left, double *q_right,
-			   double z_left, double z_right,
-			   double n1, double n2,
-			   double epsilon, double H0, double g,
-			   double *edgeflux, double *max_speed) {
+                           double z_left, double z_right,
+                           double n1, double n2,
+                           double epsilon, double H0, double g,
+                           double *edgeflux, double *max_speed) 
+{
 
   /*Compute fluxes between volumes for the shallow water wave equation
@@ -212,5 +274,5 @@
   double v_left, v_right;  
   double s_min, s_max, soundspeed_left, soundspeed_right;
-  double denom, z;
+  double denom, inverse_denominator, z;
 
   // Workspace (allocate once, use many)
@@ -219,11 +281,13 @@
   double h0 = H0*H0; // This ensures a good balance when h approaches H0.
                      // But evidence suggests that h0 can be as little as
-		     // epsilon!
+             // epsilon!
   
   // Copy conserved quantities to protect from modification
-  for (i=0; i<3; i++) {
-    q_left_rotated[i] = q_left[i];
-    q_right_rotated[i] = q_right[i];
-  }
+  q_left_rotated[0] = q_left[0];
+  q_right_rotated[0] = q_right[0];
+  q_left_rotated[1] = q_left[1];
+  q_right_rotated[1] = q_right[1];
+  q_left_rotated[2] = q_left[2];
+  q_right_rotated[2] = q_right[2];
 
   // Align x- and y-momentum with x-axis
@@ -231,17 +295,17 @@
   _rotate(q_right_rotated, n1, n2);
 
-  z = (z_left+z_right)/2; // Average elevation values. 
-                          // Even though this will nominally allow for discontinuities 
-			  // in the elevation data, there is currently no numerical 
-			  // support for this so results may be strange near jumps in the bed.
+  z = 0.5*(z_left + z_right); // Average elevation values. 
+                            // Even though this will nominally allow for discontinuities 
+                            // in the elevation data, there is currently no numerical 
+                            // support for this so results may be strange near jumps in the bed.
 
   // Compute speeds in x-direction
   w_left = q_left_rotated[0];          
-  h_left = w_left-z;
+  h_left = w_left - z;
   uh_left = q_left_rotated[1];
   u_left = _compute_speed(&uh_left, &h_left, epsilon, h0);
 
   w_right = q_right_rotated[0];
-  h_right = w_right-z;
+  h_right = w_right - z;
   uh_right = q_right_rotated[1];
   u_right = _compute_speed(&uh_right, &h_right, epsilon, h0);  
@@ -257,12 +321,21 @@
   // Maximal and minimal wave speeds
   soundspeed_left  = sqrt(g*h_left);
-  soundspeed_right = sqrt(g*h_right);
-
-  s_max = max(u_left+soundspeed_left, u_right+soundspeed_right);
-  if (s_max < 0.0) s_max = 0.0;
-
-  s_min = min(u_left-soundspeed_left, u_right-soundspeed_right);
-  if (s_min > 0.0) s_min = 0.0;
-
+  soundspeed_right = sqrt(g*h_right);  
+  
+  // Code to use fast square root optimisation if desired.
+  //soundspeed_left  = fast_squareroot_approximation(g*h_left);
+  //soundspeed_right = fast_squareroot_approximation(g*h_right);
+
+  s_max = max(u_left + soundspeed_left, u_right + soundspeed_right);
+  if (s_max < 0.0) 
+  {
+    s_max = 0.0;
+  }
+
+  s_min = min(u_left - soundspeed_left, u_right - soundspeed_right);
+  if (s_min > 0.0)
+  {
+    s_min = 0.0;
+  }
   
   // Flux formulas
@@ -275,15 +348,19 @@
   flux_right[2] = u_right*vh_right;
 
-  
   // Flux computation
-  denom = s_max-s_min;
-  if (denom < epsilon) { // FIXME (Ole): Try using H0 here
-    for (i=0; i<3; i++) edgeflux[i] = 0.0;
+  denom = s_max - s_min;
+  if (denom < epsilon) 
+  { // FIXME (Ole): Try using H0 here
+    memset(edgeflux, 0, 3*sizeof(double));
     *max_speed = 0.0;
-  } else {
-    for (i=0; i<3; i++) {
+  } 
+  else 
+  {
+    inverse_denominator = 1.0/denom;
+    for (i = 0; i < 3; i++) 
+    {
       edgeflux[i] = s_max*flux_left[i] - s_min*flux_right[i];
-      edgeflux[i] += s_max*s_min*(q_right_rotated[i]-q_left_rotated[i]);
-      edgeflux[i] /= denom;
+      edgeflux[i] += s_max*s_min*(q_right_rotated[i] - q_left_rotated[i]);
+      edgeflux[i] *= inverse_denominator;
     }
 
@@ -315,8 +392,8 @@
 // Computational function for flux computation (using stage w=z+h)
 int flux_function_kinetic(double *q_left, double *q_right,
-		  double z_left, double z_right,
-		  double n1, double n2,
-		  double epsilon, double H0, double g,
-		  double *edgeflux, double *max_speed) {
+          double z_left, double z_right,
+          double n1, double n2,
+          double epsilon, double H0, double g,
+          double *edgeflux, double *max_speed) {
 
   /*Compute fluxes between volumes for the shallow water wave equation
@@ -413,7 +490,7 @@
 
 void _manning_friction(double g, double eps, int N,
-		       double* w, double* z,
-		       double* uh, double* vh,
-		       double* eta, double* xmom, double* ymom) {
+               double* w, double* z,
+               double* uh, double* vh,
+               double* eta, double* xmom, double* ymom) {
 
   int k;
@@ -426,5 +503,5 @@
         S = -g * eta[k]*eta[k] * sqrt((uh[k]*uh[k] + vh[k]*vh[k]));
         S /= pow(h, 7.0/3);      //Expensive (on Ole's home computer)
-        //S /= exp(7.0/3.0*log(h));      //seems to save about 15% over manning_friction
+        //S /= exp((7.0/3.0)*log(h));      //seems to save about 15% over manning_friction
         //S /= h*h*(1 + h/3.0 - h*h/9.0); //FIXME: Could use a Taylor expansion
 
@@ -441,7 +518,7 @@
 /*
 void _manning_friction_explicit(double g, double eps, int N,
-		       double* w, double* z,
-		       double* uh, double* vh,
-		       double* eta, double* xmom, double* ymom) {
+               double* w, double* z,
+               double* uh, double* vh,
+               double* eta, double* xmom, double* ymom) {
 
   int k;
@@ -452,13 +529,13 @@
       h = w[k]-z[k];
       if (h >= eps) {
-	S = -g * eta[k]*eta[k] * sqrt((uh[k]*uh[k] + vh[k]*vh[k]));
-	S /= pow(h, 7.0/3);      //Expensive (on Ole's home computer)
-	//S /= exp(7.0/3.0*log(h));      //seems to save about 15% over manning_friction
-	//S /= h*h*(1 + h/3.0 - h*h/9.0); //FIXME: Could use a Taylor expansion
-
-
-	//Update momentum
-	xmom[k] += S*uh[k];
-	ymom[k] += S*vh[k];
+    S = -g * eta[k]*eta[k] * sqrt((uh[k]*uh[k] + vh[k]*vh[k]));
+    S /= pow(h, 7.0/3);      //Expensive (on Ole's home computer)
+    //S /= exp(7.0/3.0*log(h));      //seems to save about 15% over manning_friction
+    //S /= h*h*(1 + h/3.0 - h*h/9.0); //FIXME: Could use a Taylor expansion
+
+
+    //Update momentum
+    xmom[k] += S*uh[k];
+    ymom[k] += S*vh[k];
       }
     }
@@ -471,11 +548,11 @@
 
 double velocity_balance(double uh_i, 
-			double uh,
-			double h_i, 
-			double h, 
-			double alpha,
-			double epsilon) {
+            double uh,
+            double h_i, 
+            double h, 
+            double alpha,
+            double epsilon) {
   // Find alpha such that speed at the vertex is within one
-  // order of magnitude of the centroid speed	
+  // order of magnitude of the centroid speed   
 
   // FIXME(Ole): Work in progress
@@ -486,5 +563,5 @@
   
   printf("alpha = %f, uh_i=%f, uh=%f, h_i=%f, h=%f\n",
-	 alpha, uh_i, uh, h_i, h);
+     alpha, uh_i, uh, h_i, h);
       
   
@@ -500,5 +577,5 @@
   if (h < epsilon) {
     b = 1.0e10; // Limit
-  } else {	 
+  } else {   
     b = m*fabs(h_i - h)/h;
   }
@@ -507,12 +584,12 @@
 
   if (a > b) {
-    estimate = (m-1)/(a-b);		
+    estimate = (m-1)/(a-b);     
     
     printf("Alpha %f, estimate %f\n", 
-	   alpha, estimate);    
-	   
+       alpha, estimate);    
+       
     if (alpha < estimate) {
       printf("Adjusting alpha from %f to %f\n", 
-	     alpha, estimate);
+         alpha, estimate);
       alpha = estimate;
     }
@@ -520,13 +597,13 @@
   
     if (h < h_i) {
-      estimate = (m-1)/(a-b);		      
+      estimate = (m-1)/(a-b);             
     
       printf("Alpha %f, estimate %f\n", 
-	     alpha, estimate);    
-	   
+         alpha, estimate);    
+       
       if (alpha < estimate) {
-	printf("Adjusting alpha from %f to %f\n", 
-	       alpha, estimate);
-	alpha = estimate;
+    printf("Adjusting alpha from %f to %f\n", 
+           alpha, estimate);
+    alpha = estimate;
       }    
     }
@@ -540,17 +617,17 @@
 
 int _balance_deep_and_shallow(int N,
-			      double* wc,
-			      double* zc,
-			      double* wv,
-			      double* zv,
-			      double* hvbar, // Retire this
-			      double* xmomc,
-			      double* ymomc,
-			      double* xmomv,
-			      double* ymomv,
-			      double H0,
-			      int tight_slope_limiters,
-			      int use_centroid_velocities,
-			      double alpha_balance) {
+                  double* wc,
+                  double* zc,
+                  double* wv,
+                  double* zv,
+                  double* hvbar, // Retire this
+                  double* xmomc,
+                  double* ymomc,
+                  double* xmomv,
+                  double* ymomv,
+                  double H0,
+                  int tight_slope_limiters,
+                  int use_centroid_velocities,
+                  double alpha_balance) {
 
   int k, k3, i; 
@@ -579,5 +656,5 @@
       // FIXME: Try with this one precomputed
       for (i=0; i<3; i++) {
-	dz = max(dz, fabs(zv[k3+i]-zc[k]));
+    dz = max(dz, fabs(zv[k3+i]-zc[k]));
       }
     }
@@ -592,5 +669,5 @@
 
     //if (hmin < 0.0 ) {
-    //	printf("hmin = %f\n",hmin);
+    //  printf("hmin = %f\n",hmin);
     //}
     
@@ -607,7 +684,7 @@
       
       if (dz > 0.0) {
-	alpha = max( min( alpha_balance*hmin/dz, 1.0), 0.0 );      
+    alpha = max( min( alpha_balance*hmin/dz, 1.0), 0.0 );      
       } else {
-	alpha = 1.0;  // Flat bed
+    alpha = 1.0;  // Flat bed
       }
       //printf("Using old style limiter\n");
@@ -622,47 +699,47 @@
     
       if (hmin < H0) {
-	alpha = 1.0;
-	for (i=0; i<3; i++) {
-	  
-	  h_diff = hc_k - hv[i];	  
-	  if (h_diff <= 0) {
-	    // Deep water triangle is further away from bed than 
-	    // shallow water (hbar < h). Any alpha will do
-	  
-	  } else {  
-	    // Denominator is positive which means that we need some of the 
-	    // h-limited stage.
-	    
-	    alpha = min(alpha, (hc_k - H0)/h_diff);	    
-	  }
-	}
-
-	// Ensure alpha in [0,1]
-	if (alpha>1.0) alpha=1.0;
-	if (alpha<0.0) alpha=0.0;
-	
+    alpha = 1.0;
+    for (i=0; i<3; i++) {
+      
+      h_diff = hc_k - hv[i];      
+      if (h_diff <= 0) {
+        // Deep water triangle is further away from bed than 
+        // shallow water (hbar < h). Any alpha will do
+      
+      } else {  
+        // Denominator is positive which means that we need some of the 
+        // h-limited stage.
+        
+        alpha = min(alpha, (hc_k - H0)/h_diff);     
+      }
+    }
+
+    // Ensure alpha in [0,1]
+    if (alpha>1.0) alpha=1.0;
+    if (alpha<0.0) alpha=0.0;
+    
       } else {
-	// Use w-limited stage exclusively in deeper water.
-	alpha = 1.0;       
+    // Use w-limited stage exclusively in deeper water.
+    alpha = 1.0;       
       }
     }
 
 
-    //	Let
+    //  Let
     //
-    //	  wvi be the w-limited stage (wvi = zvi + hvi)
-    //	  wvi- be the h-limited state (wvi- = zvi + hvi-)
+    //    wvi be the w-limited stage (wvi = zvi + hvi)
+    //    wvi- be the h-limited state (wvi- = zvi + hvi-)
     //
     //
-    //	where i=0,1,2 denotes the vertex ids
+    //  where i=0,1,2 denotes the vertex ids
     //
     //  Weighted balance between w-limited and h-limited stage is
     //
-    //	  wvi := (1-alpha)*(zvi+hvi-) + alpha*(zvi+hvi)
+    //    wvi := (1-alpha)*(zvi+hvi-) + alpha*(zvi+hvi)
     //
     //  It follows that the updated wvi is
     //    wvi := zvi + (1-alpha)*hvi- + alpha*hvi
     //
-    //	 Momentum is balanced between constant and limited
+    //   Momentum is balanced between constant and limited
 
 
@@ -670,43 +747,43 @@
       for (i=0; i<3; i++) {
       
-	wv[k3+i] = zv[k3+i] + (1-alpha)*hc_k + alpha*hv[i];	
-
-	// Update momentum at vertices
-	if (use_centroid_velocities == 1) {
-	  // This is a simple, efficient and robust option
-	  // It uses first order approximation of velocities, but retains
-	  // the order used by stage.
-	
-	  // Speeds at centroids
-	  if (hc_k > epsilon) {
-	    uc = xmomc[k]/hc_k;
-	    vc = ymomc[k]/hc_k;
-	  } else {
-	    uc = 0.0;
-	    vc = 0.0;
-	  }
-	  
-	  // Vertex momenta guaranteed to be consistent with depth guaranteeing
-	  // controlled speed
-	  hv[i] = wv[k3+i] - zv[k3+i]; // Recompute (balanced) vertex depth
-	  xmomv[k3+i] = uc*hv[i];
-	  ymomv[k3+i] = vc*hv[i];
-	  
-	} else {
-	  // Update momentum as a linear combination of
-	  // xmomc and ymomc (shallow) and momentum
-	  // from extrapolator xmomv and ymomv (deep).
-	  // This assumes that values from xmomv and ymomv have
-	  // been established e.g. by the gradient limiter.
-
-	  // FIXME (Ole): I think this should be used with vertex momenta
-	  // computed above using centroid_velocities instead of xmomc 
-	  // and ymomc as they'll be more representative first order
-	  // values.
-	  
-	  xmomv[k3+i] = (1-alpha)*xmomc[k] + alpha*xmomv[k3+i];
-	  ymomv[k3+i] = (1-alpha)*ymomc[k] + alpha*ymomv[k3+i];
-	
-	}
+    wv[k3+i] = zv[k3+i] + (1-alpha)*hc_k + alpha*hv[i]; 
+
+    // Update momentum at vertices
+    if (use_centroid_velocities == 1) {
+      // This is a simple, efficient and robust option
+      // It uses first order approximation of velocities, but retains
+      // the order used by stage.
+    
+      // Speeds at centroids
+      if (hc_k > epsilon) {
+        uc = xmomc[k]/hc_k;
+        vc = ymomc[k]/hc_k;
+      } else {
+        uc = 0.0;
+        vc = 0.0;
+      }
+      
+      // Vertex momenta guaranteed to be consistent with depth guaranteeing
+      // controlled speed
+      hv[i] = wv[k3+i] - zv[k3+i]; // Recompute (balanced) vertex depth
+      xmomv[k3+i] = uc*hv[i];
+      ymomv[k3+i] = vc*hv[i];
+      
+    } else {
+      // Update momentum as a linear combination of
+      // xmomc and ymomc (shallow) and momentum
+      // from extrapolator xmomv and ymomv (deep).
+      // This assumes that values from xmomv and ymomv have
+      // been established e.g. by the gradient limiter.
+
+      // FIXME (Ole): I think this should be used with vertex momenta
+      // computed above using centroid_velocities instead of xmomc 
+      // and ymomc as they'll be more representative first order
+      // values.
+      
+      xmomv[k3+i] = (1-alpha)*xmomc[k] + alpha*xmomv[k3+i];
+      ymomv[k3+i] = (1-alpha)*ymomc[k] + alpha*ymomv[k3+i];
+    
+    }
       }
     }
@@ -719,11 +796,11 @@
 
 int _protect(int N,
-	     double minimum_allowed_height,
-	     double maximum_allowed_speed,
-	     double epsilon,
-	     double* wc,
-	     double* zc,
-	     double* xmomc,
-	     double* ymomc) {
+         double minimum_allowed_height,
+         double maximum_allowed_speed,
+         double epsilon,
+         double* wc,
+         double* zc,
+         double* xmomc,
+         double* ymomc) {
 
   int k;
@@ -738,9 +815,9 @@
 
       if (hc < minimum_allowed_height) {
-    	
-	// Set momentum to zero and ensure h is non negative
-	xmomc[k] = 0.0;
-	ymomc[k] = 0.0;
-	if (hc <= 0.0) wc[k] = zc[k];
+        
+    // Set momentum to zero and ensure h is non negative
+    xmomc[k] = 0.0;
+    ymomc[k] = 0.0;
+    if (hc <= 0.0) wc[k] = zc[k];
       }
     }
@@ -757,27 +834,27 @@
               
         if (hc <= 0.0) {
-        	wc[k] = zc[k];
-    	xmomc[k] = 0.0;
-    	ymomc[k] = 0.0;
+            wc[k] = zc[k];
+        xmomc[k] = 0.0;
+        ymomc[k] = 0.0;
         } else {
           //Reduce excessive speeds derived from division by small hc
-    	//FIXME (Ole): This may be unnecessary with new slope limiters 
-    	//in effect.
+        //FIXME (Ole): This may be unnecessary with new slope limiters 
+        //in effect.
           
           u = xmomc[k]/hc;
-	  if (fabs(u) > maximum_allowed_speed) {
-	    reduced_speed = maximum_allowed_speed * u/fabs(u);
-	    //printf("Speed (u) has been reduced from %.3f to %.3f\n",
-	    //	 u, reduced_speed);
-	    xmomc[k] = reduced_speed * hc;
-	  }
+      if (fabs(u) > maximum_allowed_speed) {
+        reduced_speed = maximum_allowed_speed * u/fabs(u);
+        //printf("Speed (u) has been reduced from %.3f to %.3f\n",
+        //   u, reduced_speed);
+        xmomc[k] = reduced_speed * hc;
+      }
 
           v = ymomc[k]/hc;
-	  if (fabs(v) > maximum_allowed_speed) {
-	    reduced_speed = maximum_allowed_speed * v/fabs(v);
-	    //printf("Speed (v) has been reduced from %.3f to %.3f\n",
-	    //	 v, reduced_speed);
-	    ymomc[k] = reduced_speed * hc;
-	  }
+      if (fabs(v) > maximum_allowed_speed) {
+        reduced_speed = maximum_allowed_speed * v/fabs(v);
+        //printf("Speed (v) has been reduced from %.3f to %.3f\n",
+        //   v, reduced_speed);
+        ymomc[k] = reduced_speed * hc;
+      }
         }
       }
@@ -790,9 +867,9 @@
 
 int _assign_wind_field_values(int N,
-			      double* xmom_update,
-			      double* ymom_update,
-			      double* s_vec,
-			      double* phi_vec,
-			      double cw) {
+                  double* xmom_update,
+                  double* ymom_update,
+                  double* s_vec,
+                  double* phi_vec,
+                  double cw) {
 
   // Assign windfield values to momentum updates
@@ -839,6 +916,6 @@
 
   if (!PyArg_ParseTuple(args, "OOOddOddd",
-			&normal, &ql, &qr, &zl, &zr, &edgeflux,
-			&epsilon, &g, &H0)) {
+            &normal, &ql, &qr, &zl, &zr, &edgeflux,
+            &epsilon, &g, &H0)) {
     PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: flux_function_central could not parse input arguments");
     return NULL;
@@ -847,12 +924,12 @@
   
   _flux_function_central((double*) ql -> data, 
-			 (double*) qr -> data, 
-			 zl, 
-			 zr, 			 			 
-			 ((double*) normal -> data)[0],
-			 ((double*) normal -> data)[1],			 
-			 epsilon, H0, g,
-			 (double*) edgeflux -> data, 
-			 &max_speed);
+             (double*) qr -> data, 
+             zl, 
+             zr,                         
+             ((double*) normal -> data)[0],
+             ((double*) normal -> data)[1],          
+             epsilon, H0, g,
+             (double*) edgeflux -> data, 
+             &max_speed);
   
   return Py_BuildValue("d", max_speed);  
@@ -874,6 +951,6 @@
 
   if (!PyArg_ParseTuple(args, "dOOOOO",
-			&g, &h, &v, &x,
-			&xmom, &ymom)) {
+            &g, &h, &v, &x,
+            &xmom, &ymom)) {
     //&epsilon)) {
     PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: gravity could not parse input arguments");
@@ -940,6 +1017,6 @@
 
   if (!PyArg_ParseTuple(args, "ddOOOOOOO",
-			&g, &eps, &w, &z, &uh, &vh, &eta,
-			&xmom, &ymom)) {
+            &g, &eps, &w, &z, &uh, &vh, &eta,
+            &xmom, &ymom)) {
     PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: manning_friction could not parse input arguments");
     return NULL;
@@ -957,11 +1034,11 @@
   N = w -> dimensions[0];
   _manning_friction(g, eps, N,
-		    (double*) w -> data,
-		    (double*) z -> data,
-		    (double*) uh -> data,
-		    (double*) vh -> data,
-		    (double*) eta -> data,
-		    (double*) xmom -> data,
-		    (double*) ymom -> data);
+            (double*) w -> data,
+            (double*) z -> data,
+            (double*) uh -> data,
+            (double*) vh -> data,
+            (double*) eta -> data,
+            (double*) xmom -> data,
+            (double*) ymom -> data);
 
   return Py_BuildValue("");
@@ -981,6 +1058,6 @@
 
   if (!PyArg_ParseTuple(args, "ddOOOOOOO",
-			&g, &eps, &w, &z, &uh, &vh, &eta,
-			&xmom, &ymom))
+            &g, &eps, &w, &z, &uh, &vh, &eta,
+            &xmom, &ymom))
     return NULL;
 
@@ -996,11 +1073,11 @@
   N = w -> dimensions[0];
   _manning_friction_explicit(g, eps, N,
-		    (double*) w -> data,
-		    (double*) z -> data,
-		    (double*) uh -> data,
-		    (double*) vh -> data,
-		    (double*) eta -> data,
-		    (double*) xmom -> data,
-		    (double*) ymom -> data);
+            (double*) w -> data,
+            (double*) z -> data,
+            (double*) uh -> data,
+            (double*) vh -> data,
+            (double*) eta -> data,
+            (double*) xmom -> data,
+            (double*) ymom -> data);
 
   return Py_BuildValue("");
@@ -1012,43 +1089,44 @@
 // Computational routine
 int _extrapolate_second_order_sw(int number_of_elements,
-				  double epsilon,
-				  double minimum_allowed_height,
-				  double beta_w,
-				  double beta_w_dry,
-				  double beta_uh,
-				  double beta_uh_dry,
-				  double beta_vh,
-				  double beta_vh_dry,
-				  long* surrogate_neighbours,
-				  long* number_of_boundaries,
-				  double* centroid_coordinates,
-				  double* stage_centroid_values,
-				  double* xmom_centroid_values,
-				  double* ymom_centroid_values,
-				  double* elevation_centroid_values,
-				  double* vertex_coordinates,
-				  double* stage_vertex_values,
-				  double* xmom_vertex_values,
-				  double* ymom_vertex_values,
-				  double* elevation_vertex_values,
-				  int optimise_dry_cells) {
-				  
-				  
+                                 double epsilon,
+                                 double minimum_allowed_height,
+                                 double beta_w,
+                                 double beta_w_dry,
+                                 double beta_uh,
+                                 double beta_uh_dry,
+                                 double beta_vh,
+                                 double beta_vh_dry,
+                                 long* surrogate_neighbours,
+                                 long* number_of_boundaries,
+                                 double* centroid_coordinates,
+                                 double* stage_centroid_values,
+                                 double* xmom_centroid_values,
+                                 double* ymom_centroid_values,
+                                 double* elevation_centroid_values,
+                                 double* vertex_coordinates,
+                                 double* stage_vertex_values,
+                                 double* xmom_vertex_values,
+                                 double* ymom_vertex_values,
+                                 double* elevation_vertex_values,
+                                 int optimise_dry_cells) {
+                  
+                  
 
   // Local variables
   double a, b; // Gradient vector used to calculate vertex values from centroids
-  int k,k0,k1,k2,k3,k6,coord_index,i;
-  double x,y,x0,y0,x1,y1,x2,y2,xv0,yv0,xv1,yv1,xv2,yv2; // Vertices of the auxiliary triangle
-  double dx1,dx2,dy1,dy2,dxv0,dxv1,dxv2,dyv0,dyv1,dyv2,dq0,dq1,dq2,area2;
+  int k, k0, k1, k2, k3, k6, coord_index, i;
+  double x, y, x0, y0, x1, y1, x2, y2, xv0, yv0, xv1, yv1, xv2, yv2; // Vertices of the auxiliary triangle
+  double dx1, dx2, dy1, dy2, dxv0, dxv1, dxv2, dyv0, dyv1, dyv2, dq0, dq1, dq2, area2, inv_area2;
   double dqv[3], qmin, qmax, hmin, hmax;
   double hc, h0, h1, h2, beta_tmp, hfactor;
 
-	
-  for (k=0; k<number_of_elements; k++) {
+    
+  for (k = 0; k < number_of_elements; k++) 
+  {
     k3=k*3;
     k6=k*6;
 
-    
-    if (number_of_boundaries[k]==3){
+    if (number_of_boundaries[k]==3)
+    {
       // No neighbours, set gradient on the triangle to zero
       
@@ -1065,28 +1143,36 @@
       continue;
     }
-    else {
+    else 
+    {
       // Triangle k has one or more neighbours. 
       // Get centroid and vertex coordinates of the triangle
       
       // Get the vertex coordinates
-      xv0 = vertex_coordinates[k6];   yv0=vertex_coordinates[k6+1];
-      xv1 = vertex_coordinates[k6+2]; yv1=vertex_coordinates[k6+3];
-      xv2 = vertex_coordinates[k6+4]; yv2=vertex_coordinates[k6+5];
+      xv0 = vertex_coordinates[k6];   
+      yv0 = vertex_coordinates[k6+1];
+      xv1 = vertex_coordinates[k6+2]; 
+      yv1 = vertex_coordinates[k6+3];
+      xv2 = vertex_coordinates[k6+4]; 
+      yv2 = vertex_coordinates[k6+5];
       
       // Get the centroid coordinates
-      coord_index=2*k;
-      x=centroid_coordinates[coord_index];
-      y=centroid_coordinates[coord_index+1];
+      coord_index = 2*k;
+      x = centroid_coordinates[coord_index];
+      y = centroid_coordinates[coord_index+1];
       
       // Store x- and y- differentials for the vertices of 
       // triangle k relative to the centroid
-      dxv0=xv0-x; dxv1=xv1-x; dxv2=xv2-x;
-      dyv0=yv0-y; dyv1=yv1-y; dyv2=yv2-y;
+      dxv0 = xv0 - x; 
+      dxv1 = xv1 - x; 
+      dxv2 = xv2 - x;
+      dyv0 = yv0 - y; 
+      dyv1 = yv1 - y; 
+      dyv2 = yv2 - y;
     }
 
 
             
-    if (number_of_boundaries[k]<=1){
-    
+    if (number_of_boundaries[k]<=1)
+    {
       //==============================================
       // Number of boundaries <= 1
@@ -1099,26 +1185,28 @@
       // from this centroid and its two neighbours
       
-      k0=surrogate_neighbours[k3];
-      k1=surrogate_neighbours[k3+1];
-      k2=surrogate_neighbours[k3+2];
+      k0 = surrogate_neighbours[k3];
+      k1 = surrogate_neighbours[k3 + 1];
+      k2 = surrogate_neighbours[k3 + 2];
       
       // Get the auxiliary triangle's vertex coordinates 
       // (really the centroids of neighbouring triangles)
-      coord_index=2*k0;
-      x0=centroid_coordinates[coord_index];
-      y0=centroid_coordinates[coord_index+1];
-      
-      coord_index=2*k1;
-      x1=centroid_coordinates[coord_index];
-      y1=centroid_coordinates[coord_index+1];
-      
-      coord_index=2*k2;
-      x2=centroid_coordinates[coord_index];
-      y2=centroid_coordinates[coord_index+1];
+      coord_index = 2*k0;
+      x0 = centroid_coordinates[coord_index];
+      y0 = centroid_coordinates[coord_index+1];
+      
+      coord_index = 2*k1;
+      x1 = centroid_coordinates[coord_index];
+      y1 = centroid_coordinates[coord_index+1];
+      
+      coord_index = 2*k2;
+      x2 = centroid_coordinates[coord_index];
+      y2 = centroid_coordinates[coord_index+1];
       
       // Store x- and y- differentials for the vertices 
       // of the auxiliary triangle
-      dx1=x1-x0; dx2=x2-x0;
-      dy1=y1-y0; dy2=y2-y0;
+      dx1 = x1 - x0; 
+      dx2 = x2 - x0;
+      dy1 = y1 - y0; 
+      dy2 = y2 - y0;
       
       // Calculate 2*area of the auxiliary triangle
@@ -1128,8 +1216,10 @@
       // If the mesh is 'weird' near the boundary, 
       // the triangle might be flat or clockwise:
-      if (area2<=0) {
-	PyErr_SetString(PyExc_RuntimeError, 
-			"shallow_water_ext.c: negative triangle area encountered");
-	return -1;
+      if (area2 <= 0) 
+      {
+        PyErr_SetString(PyExc_RuntimeError, 
+                        "shallow_water_ext.c: negative triangle area encountered");
+    
+        return -1;
       }  
       
@@ -1139,23 +1229,25 @@
       h1 = stage_centroid_values[k1] - elevation_centroid_values[k1];
       h2 = stage_centroid_values[k2] - elevation_centroid_values[k2];
-      hmin = min(min(h0,min(h1,h2)),hc);
+      hmin = min(min(h0, min(h1, h2)), hc);
       //hfactor = hc/(hc + 1.0);
 
       hfactor = 0.0;
-      if (hmin > 0.001 ) {
-	  hfactor = (hmin-0.001)/(hmin+0.004);
-      }
-      
-      if (optimise_dry_cells) {      
-	// Check if linear reconstruction is necessary for triangle k
-	// This check will exclude dry cells.
-
-	hmax = max(h0,max(h1,h2));      
-	if (hmax < epsilon) {
-	  continue;
-	}
-      }
-
-            
+      if (hmin > 0.001) 
+      {
+        hfactor = (hmin - 0.001)/(hmin + 0.004);
+      }
+      
+      if (optimise_dry_cells) 
+      {      
+        // Check if linear reconstruction is necessary for triangle k
+        // This check will exclude dry cells.
+
+        hmax = max(h0, max(h1, h2));      
+        if (hmax < epsilon) 
+        {
+            continue;
+        }
+      }
+    
       //-----------------------------------
       // stage
@@ -1164,27 +1256,28 @@
       // Calculate the difference between vertex 0 of the auxiliary 
       // triangle and the centroid of triangle k
-      dq0=stage_centroid_values[k0]-stage_centroid_values[k];
+      dq0 = stage_centroid_values[k0] - stage_centroid_values[k];
       
       // Calculate differentials between the vertices 
       // of the auxiliary triangle (centroids of neighbouring triangles)
-      dq1=stage_centroid_values[k1]-stage_centroid_values[k0];
-      dq2=stage_centroid_values[k2]-stage_centroid_values[k0];
-      
+      dq1 = stage_centroid_values[k1] - stage_centroid_values[k0];
+      dq2 = stage_centroid_values[k2] - stage_centroid_values[k0];
+      
+	  inv_area2 = 1.0/area2;
       // Calculate the gradient of stage on the auxiliary triangle
       a = dy2*dq1 - dy1*dq2;
-      a /= area2;
+      a *= inv_area2;
       b = dx1*dq2 - dx2*dq1;
-      b /= area2;
+      b *= inv_area2;
       
       // Calculate provisional jumps in stage from the centroid 
       // of triangle k to its vertices, to be limited
-      dqv[0]=a*dxv0+b*dyv0;
-      dqv[1]=a*dxv1+b*dyv1;
-      dqv[2]=a*dxv2+b*dyv2;
+      dqv[0] = a*dxv0 + b*dyv0;
+      dqv[1] = a*dxv1 + b*dyv1;
+      dqv[2] = a*dxv2 + b*dyv2;
       
       // Now we want to find min and max of the centroid and the 
       // vertices of the auxiliary triangle and compute jumps 
       // from the centroid to the min and max
-      find_qmin_and_qmax(dq0,dq1,dq2,&qmin,&qmax);
+      find_qmin_and_qmax(dq0, dq1, dq2, &qmin, &qmax);
       
       // Playing with dry wet interface
@@ -1193,5 +1286,5 @@
       //if (hmin>minimum_allowed_height)
       beta_tmp = beta_w_dry + (beta_w - beta_w_dry) * hfactor;
-	
+    
       //printf("min_alled_height = %f\n",minimum_allowed_height);
       //printf("hmin = %f\n",hmin);
@@ -1199,8 +1292,10 @@
       //printf("beta_tmp = %f\n",beta_tmp);
       // Limit the gradient
-      limit_gradient(dqv,qmin,qmax,beta_tmp); 
-      
-      for (i=0;i<3;i++)
-	stage_vertex_values[k3+i]=stage_centroid_values[k]+dqv[i];
+      limit_gradient(dqv, qmin, qmax, beta_tmp); 
+      
+      //for (i=0;i<3;i++)
+      stage_vertex_values[k3+0] = stage_centroid_values[k] + dqv[0];
+	  stage_vertex_values[k3+1] = stage_centroid_values[k] + dqv[1];
+	  stage_vertex_values[k3+2] = stage_centroid_values[k] + dqv[2];
       
       
@@ -1211,27 +1306,27 @@
       // Calculate the difference between vertex 0 of the auxiliary 
       // triangle and the centroid of triangle k      
-      dq0=xmom_centroid_values[k0]-xmom_centroid_values[k];
+      dq0 = xmom_centroid_values[k0] - xmom_centroid_values[k];
       
       // Calculate differentials between the vertices 
       // of the auxiliary triangle
-      dq1=xmom_centroid_values[k1]-xmom_centroid_values[k0];
-      dq2=xmom_centroid_values[k2]-xmom_centroid_values[k0];
+      dq1 = xmom_centroid_values[k1] - xmom_centroid_values[k0];
+      dq2 = xmom_centroid_values[k2] - xmom_centroid_values[k0];
       
       // Calculate the gradient of xmom on the auxiliary triangle
       a = dy2*dq1 - dy1*dq2;
-      a /= area2;
+      a *= inv_area2;
       b = dx1*dq2 - dx2*dq1;
-      b /= area2;
+      b *= inv_area2;
       
       // Calculate provisional jumps in stage from the centroid 
       // of triangle k to its vertices, to be limited      
-      dqv[0]=a*dxv0+b*dyv0;
-      dqv[1]=a*dxv1+b*dyv1;
-      dqv[2]=a*dxv2+b*dyv2;
+      dqv[0] = a*dxv0+b*dyv0;
+      dqv[1] = a*dxv1+b*dyv1;
+      dqv[2] = a*dxv2+b*dyv2;
       
       // Now we want to find min and max of the centroid and the 
       // vertices of the auxiliary triangle and compute jumps 
       // from the centroid to the min and max
-      find_qmin_and_qmax(dq0,dq1,dq2,&qmin,&qmax);
+      find_qmin_and_qmax(dq0, dq1, dq2, &qmin, &qmax);
       //beta_tmp = beta_uh;
       //if (hmin<minimum_allowed_height)
@@ -1240,9 +1335,10 @@
 
       // Limit the gradient
-      limit_gradient(dqv,qmin,qmax,beta_tmp);
-
-      for (i=0;i<3;i++)
-	xmom_vertex_values[k3+i]=xmom_centroid_values[k]+dqv[i];
-      
+      limit_gradient(dqv, qmin, qmax, beta_tmp);
+
+      for (i=0; i < 3; i++)
+      {
+        xmom_vertex_values[k3+i] = xmom_centroid_values[k] + dqv[i];
+      }
       
       //-----------------------------------
@@ -1252,27 +1348,27 @@
       // Calculate the difference between vertex 0 of the auxiliary 
       // triangle and the centroid of triangle k
-      dq0=ymom_centroid_values[k0]-ymom_centroid_values[k];
+      dq0 = ymom_centroid_values[k0] - ymom_centroid_values[k];
       
       // Calculate differentials between the vertices 
       // of the auxiliary triangle
-      dq1=ymom_centroid_values[k1]-ymom_centroid_values[k0];
-      dq2=ymom_centroid_values[k2]-ymom_centroid_values[k0];
+      dq1 = ymom_centroid_values[k1] - ymom_centroid_values[k0];
+      dq2 = ymom_centroid_values[k2] - ymom_centroid_values[k0];
       
       // Calculate the gradient of xmom on the auxiliary triangle
       a = dy2*dq1 - dy1*dq2;
-      a /= area2;
+      a *= inv_area2;
       b = dx1*dq2 - dx2*dq1;
-      b /= area2;
+      b *= inv_area2;
       
       // Calculate provisional jumps in stage from the centroid 
       // of triangle k to its vertices, to be limited
-      dqv[0]=a*dxv0+b*dyv0;
-      dqv[1]=a*dxv1+b*dyv1;
-      dqv[2]=a*dxv2+b*dyv2;
+      dqv[0] = a*dxv0 + b*dyv0;
+      dqv[1] = a*dxv1 + b*dyv1;
+      dqv[2] = a*dxv2 + b*dyv2;
       
       // Now we want to find min and max of the centroid and the 
       // vertices of the auxiliary triangle and compute jumps 
       // from the centroid to the min and max
-      find_qmin_and_qmax(dq0,dq1,dq2,&qmin,&qmax);
+      find_qmin_and_qmax(dq0, dq1, dq2, &qmin, &qmax);
       
       //beta_tmp = beta_vh;
@@ -1280,14 +1376,16 @@
       //if (hmin<minimum_allowed_height)
       //beta_tmp = beta_vh_dry;
-      beta_tmp = beta_vh_dry + (beta_vh - beta_vh_dry) * hfactor;	
+      beta_tmp = beta_vh_dry + (beta_vh - beta_vh_dry) * hfactor;   
 
       // Limit the gradient
-      limit_gradient(dqv,qmin,qmax,beta_tmp);
+      limit_gradient(dqv, qmin, qmax, beta_tmp);
       
       for (i=0;i<3;i++)
-	ymom_vertex_values[k3+i]=ymom_centroid_values[k]+dqv[i];
-	
+      {
+        ymom_vertex_values[k3 + i] = ymom_centroid_values[k] + dqv[i];
+      }
     } // End number_of_boundaries <=1 
-    else{
+    else
+    {
 
       //==============================================
@@ -1298,33 +1396,38 @@
       
       // Find the only internal neighbour (k1?)
-      for (k2=k3;k2<k3+3;k2++){
-	// Find internal neighbour of triangle k      
-	// k2 indexes the edges of triangle k	
-      
-	if (surrogate_neighbours[k2]!=k)
-	  break;
-      }
-      
-      if ((k2==k3+3)) {
-	// If we didn't find an internal neighbour
-	PyErr_SetString(PyExc_RuntimeError, 
-			"shallow_water_ext.c: Internal neighbour not found");      
-	return -1;
-      }
-      
-      k1=surrogate_neighbours[k2];
+      for (k2 = k3; k2 < k3 + 3; k2++)
+      {
+      // Find internal neighbour of triangle k      
+      // k2 indexes the edges of triangle k   
+      
+          if (surrogate_neighbours[k2] != k)
+          {
+             break;
+          }
+      }
+      
+      if ((k2 == k3 + 3)) 
+      {
+        // If we didn't find an internal neighbour
+        PyErr_SetString(PyExc_RuntimeError, 
+                        "shallow_water_ext.c: Internal neighbour not found");      
+        return -1;
+      }
+      
+      k1 = surrogate_neighbours[k2];
       
       // The coordinates of the triangle are already (x,y). 
       // Get centroid of the neighbour (x1,y1)
-      coord_index=2*k1;
-      x1=centroid_coordinates[coord_index];
-      y1=centroid_coordinates[coord_index+1];
+      coord_index = 2*k1;
+      x1 = centroid_coordinates[coord_index];
+      y1 = centroid_coordinates[coord_index + 1];
       
       // Compute x- and y- distances between the centroid of 
       // triangle k and that of its neighbour
-      dx1=x1-x; dy1=y1-y;
+      dx1 = x1 - x; 
+      dy1 = y1 - y;
       
       // Set area2 as the square of the distance
-      area2=dx1*dx1+dy1*dy1;
+      area2 = dx1*dx1 + dy1*dy1;
       
       // Set dx2=(x1-x0)/((x1-x0)^2+(y1-y0)^2) 
@@ -1332,7 +1435,7 @@
       // respectively correspond to the x- and y- gradients 
       // of the conserved quantities
-      dx2=1.0/area2;
-      dy2=dx2*dy1;
-      dx2*=dx1;
+      dx2 = 1.0/area2;
+      dy2 = dx2*dy1;
+      dx2 *= dx1;
       
       
@@ -1342,32 +1445,37 @@
 
       // Compute differentials
-      dq1=stage_centroid_values[k1]-stage_centroid_values[k];
+      dq1 = stage_centroid_values[k1] - stage_centroid_values[k];
       
       // Calculate the gradient between the centroid of triangle k 
       // and that of its neighbour
-      a=dq1*dx2;
-      b=dq1*dy2;
+      a = dq1*dx2;
+      b = dq1*dy2;
       
       // Calculate provisional vertex jumps, to be limited
-      dqv[0]=a*dxv0+b*dyv0;
-      dqv[1]=a*dxv1+b*dyv1;
-      dqv[2]=a*dxv2+b*dyv2;
+      dqv[0] = a*dxv0 + b*dyv0;
+      dqv[1] = a*dxv1 + b*dyv1;
+      dqv[2] = a*dxv2 + b*dyv2;
       
       // Now limit the jumps
-      if (dq1>=0.0){
-	qmin=0.0;
-	qmax=dq1;
-      }
-      else{
-	qmin=dq1;
-	qmax=0.0;
+      if (dq1>=0.0)
+      {
+        qmin=0.0;
+        qmax=dq1;
+      }
+      else
+      {
+        qmin = dq1;
+        qmax = 0.0;
       }
       
       // Limit the gradient
-      limit_gradient(dqv,qmin,qmax,beta_w);
-      
-      for (i=0;i<3;i++)
-	stage_vertex_values[k3+i]=stage_centroid_values[k]+dqv[i];
-      
+      limit_gradient(dqv, qmin, qmax, beta_w);
+      
+      //for (i=0; i < 3; i++)
+      //{
+      stage_vertex_values[k3] = stage_centroid_values[k] + dqv[0];
+      stage_vertex_values[k3 + 1] = stage_centroid_values[k] + dqv[1];
+      stage_vertex_values[k3 + 2] = stage_centroid_values[k] + dqv[2];
+      //}
       
       //-----------------------------------
@@ -1376,32 +1484,40 @@
       
       // Compute differentials
-      dq1=xmom_centroid_values[k1]-xmom_centroid_values[k];
+      dq1 = xmom_centroid_values[k1] - xmom_centroid_values[k];
       
       // Calculate the gradient between the centroid of triangle k 
       // and that of its neighbour
-      a=dq1*dx2;
-      b=dq1*dy2;
+      a = dq1*dx2;
+      b = dq1*dy2;
       
       // Calculate provisional vertex jumps, to be limited
-      dqv[0]=a*dxv0+b*dyv0;
-      dqv[1]=a*dxv1+b*dyv1;
-      dqv[2]=a*dxv2+b*dyv2;
+      dqv[0] = a*dxv0+b*dyv0;
+      dqv[1] = a*dxv1+b*dyv1;
+      dqv[2] = a*dxv2+b*dyv2;
       
       // Now limit the jumps
-      if (dq1>=0.0){
-	qmin=0.0;
-	qmax=dq1;
-      }
-      else{
-	qmin=dq1;
-	qmax=0.0;
+      if (dq1 >= 0.0)
+      {
+        qmin = 0.0;
+        qmax = dq1;
+      }
+      else
+      {
+        qmin = dq1;
+        qmax = 0.0;
       }
       
       // Limit the gradient      
-      limit_gradient(dqv,qmin,qmax,beta_w);
-      
-      for (i=0;i<3;i++)
-	xmom_vertex_values[k3+i]=xmom_centroid_values[k]+dqv[i];
-      
+      limit_gradient(dqv, qmin, qmax, beta_w);
+      
+      //for (i=0;i<3;i++)
+      //xmom_vertex_values[k3] = xmom_centroid_values[k] + dqv[0];
+      //xmom_vertex_values[k3 + 1] = xmom_centroid_values[k] + dqv[1];
+      //xmom_vertex_values[k3 + 2] = xmom_centroid_values[k] + dqv[2];
+      
+      for (i = 0; i < 3;i++)
+      {
+          xmom_vertex_values[k3 + i] = xmom_centroid_values[k] + dqv[i];
+      }
       
       //-----------------------------------
@@ -1410,37 +1526,48 @@
 
       // Compute differentials
-      dq1=ymom_centroid_values[k1]-ymom_centroid_values[k];
+      dq1 = ymom_centroid_values[k1] - ymom_centroid_values[k];
       
       // Calculate the gradient between the centroid of triangle k 
       // and that of its neighbour
-      a=dq1*dx2;
-      b=dq1*dy2;
+      a = dq1*dx2;
+      b = dq1*dy2;
       
       // Calculate provisional vertex jumps, to be limited
-      dqv[0]=a*dxv0+b*dyv0;
-      dqv[1]=a*dxv1+b*dyv1;
-      dqv[2]=a*dxv2+b*dyv2;
+      dqv[0] = a*dxv0 + b*dyv0;
+      dqv[1] = a*dxv1 + b*dyv1;
+      dqv[2] = a*dxv2 + b*dyv2;
       
       // Now limit the jumps
-      if (dq1>=0.0){
-	qmin=0.0;
-	qmax=dq1;
-      }
-      else{
-	qmin=dq1;
-	qmax=0.0;
+      if (dq1>=0.0)
+      {
+        qmin = 0.0;
+        qmax = dq1;
+      } 
+      else
+      {
+        qmin = dq1;
+        qmax = 0.0;
       }
       
       // Limit the gradient
-      limit_gradient(dqv,qmin,qmax,beta_w);
-      
-      for (i=0;i<3;i++)
-	ymom_vertex_values[k3+i]=ymom_centroid_values[k]+dqv[i];
-	
+      limit_gradient(dqv, qmin, qmax, beta_w);
+      
+      //for (i=0;i<3;i++)
+      //ymom_vertex_values[k3] = ymom_centroid_values[k] + dqv[0];
+      //ymom_vertex_values[k3 + 1] = ymom_centroid_values[k] + dqv[1];
+      //ymom_vertex_values[k3 + 2] = ymom_centroid_values[k] + dqv[2];
+
+for (i=0;i<3;i++)
+        {
+ymom_vertex_values[k3 + i] = ymom_centroid_values[k] + dqv[i];
+        }
+//ymom_vertex_values[k3] = ymom_centroid_values[k] + dqv[0];
+//ymom_vertex_values[k3 + 1] = ymom_centroid_values[k] + dqv[1];
+//ymom_vertex_values[k3 + 2] = ymom_centroid_values[k] + dqv[2];
     } // else [number_of_boundaries==2]
   } // for k=0 to number_of_elements-1
   
   return 0;
-}			
+}           
 
 
@@ -1477,6 +1604,6 @@
     Post conditions:
             The vertices of each triangle have values from a 
-	    limited linear reconstruction
-	    based on centroid values
+        limited linear reconstruction
+        based on centroid values
 
   */
@@ -1505,21 +1632,21 @@
   // Convert Python arguments to C
   if (!PyArg_ParseTuple(args, "OOOOOOOOOOOOOi",
-			&domain,
-			&surrogate_neighbours,
-			&number_of_boundaries,
-			&centroid_coordinates,
-			&stage_centroid_values,
-			&xmom_centroid_values,
-			&ymom_centroid_values,
-			&elevation_centroid_values,
-			&vertex_coordinates,
-			&stage_vertex_values,
-			&xmom_vertex_values,
-			&ymom_vertex_values,
-			&elevation_vertex_values,
-			&optimise_dry_cells)) {			
-			
+            &domain,
+            &surrogate_neighbours,
+            &number_of_boundaries,
+            &centroid_coordinates,
+            &stage_centroid_values,
+            &xmom_centroid_values,
+            &ymom_centroid_values,
+            &elevation_centroid_values,
+            &vertex_coordinates,
+            &stage_vertex_values,
+            &xmom_vertex_values,
+            &ymom_vertex_values,
+            &elevation_vertex_values,
+            &optimise_dry_cells)) {         
+            
     PyErr_SetString(PyExc_RuntimeError, 
-		    "Input arguments to extrapolate_second_order_sw failed");
+            "Input arguments to extrapolate_second_order_sw failed");
     return NULL;
   }
@@ -1557,29 +1684,29 @@
   // Call underlying computational routine
   e = _extrapolate_second_order_sw(number_of_elements,
-				   epsilon,
-				   minimum_allowed_height,
-				   beta_w,
-				   beta_w_dry,
-				   beta_uh,
-				   beta_uh_dry,
-				   beta_vh,
-				   beta_vh_dry,
-				   (long*) surrogate_neighbours -> data,
-				   (long*) number_of_boundaries -> data,
-				   (double*) centroid_coordinates -> data,
-				   (double*) stage_centroid_values -> data,
-				   (double*) xmom_centroid_values -> data,
-				   (double*) ymom_centroid_values -> data,
-				   (double*) elevation_centroid_values -> data,
-				   (double*) vertex_coordinates -> data,
-				   (double*) stage_vertex_values -> data,
-				   (double*) xmom_vertex_values -> data,
-				   (double*) ymom_vertex_values -> data,
-				   (double*) elevation_vertex_values -> data,
-				   optimise_dry_cells);
+                   epsilon,
+                   minimum_allowed_height,
+                   beta_w,
+                   beta_w_dry,
+                   beta_uh,
+                   beta_uh_dry,
+                   beta_vh,
+                   beta_vh_dry,
+                   (long*) surrogate_neighbours -> data,
+                   (long*) number_of_boundaries -> data,
+                   (double*) centroid_coordinates -> data,
+                   (double*) stage_centroid_values -> data,
+                   (double*) xmom_centroid_values -> data,
+                   (double*) ymom_centroid_values -> data,
+                   (double*) elevation_centroid_values -> data,
+                   (double*) vertex_coordinates -> data,
+                   (double*) stage_vertex_values -> data,
+                   (double*) xmom_vertex_values -> data,
+                   (double*) ymom_vertex_values -> data,
+                   (double*) elevation_vertex_values -> data,
+                   optimise_dry_cells);
   if (e == -1) {
     // Use error string set inside computational routine
     return NULL;
-  }  				  
+  }                   
   
   
@@ -1609,5 +1736,5 @@
   // Convert Python arguments to C
   if (!PyArg_ParseTupleAndKeywords(args, kwargs, "OO|i", argnames,
-				   &Q, &Normal, &direction)) {
+                   &Q, &Normal, &direction)) {
     PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: rotate could not parse input arguments");
     return NULL;
@@ -1654,31 +1781,31 @@
 // Computational function for flux computation
 double _compute_fluxes_central(int number_of_elements,
-			       double timestep,
-			       double epsilon,
-			       double H0,
-			       double g,
-			       long* neighbours,
-			       long* neighbour_edges,
-			       double* normals,
-			       double* edgelengths, 
-			       double* radii, 
-			       double* areas,
-			       long* tri_full_flag,
-			       double* stage_edge_values,
-			       double* xmom_edge_values,
-			       double* ymom_edge_values,
-			       double* bed_edge_values,
-			       double* stage_boundary_values,
-			       double* xmom_boundary_values,
-			       double* ymom_boundary_values,
-			       double* stage_explicit_update,
-			       double* xmom_explicit_update,
-			       double* ymom_explicit_update,
-			       long* already_computed_flux,
-			       double* max_speed_array,
-			       int optimise_dry_cells) {
-			       
+                               double timestep,
+                               double epsilon,
+                               double H0,
+                               double g,
+                               long* neighbours,
+                               long* neighbour_edges,
+                               double* normals,
+                               double* edgelengths, 
+                               double* radii, 
+                               double* areas,
+                               long* tri_full_flag,
+                               double* stage_edge_values,
+                               double* xmom_edge_values,
+                               double* ymom_edge_values,
+                               double* bed_edge_values,
+                               double* stage_boundary_values,
+                               double* xmom_boundary_values,
+                               double* ymom_boundary_values,
+                               double* stage_explicit_update,
+                               double* xmom_explicit_update,
+                               double* ymom_explicit_update,
+                               long* already_computed_flux,
+                               double* max_speed_array,
+                               int optimise_dry_cells) 
+{                   
   // Local variables
-  double max_speed, length, area, zl, zr;
+  double max_speed, length, inv_area, zl, zr;
   int k, i, m, n;
   int ki, nm=0, ki2; // Index shorthands
@@ -1687,30 +1814,30 @@
   double ql[3], qr[3], edgeflux[3]; // Work array for summing up fluxes
 
-  static long call=1; // Static local variable flagging already computed flux
-			       
-	
+  static long call = 1; // Static local variable flagging already computed flux
+                   
   // Start computation
   call++; // Flag 'id' of flux calculation for this timestep 
-  
+
   // Set explicit_update to zero for all conserved_quantities.
   // This assumes compute_fluxes called before forcing terms
-  for (k=0; k<number_of_elements; k++) {
-    stage_explicit_update[k]=0.0;
-    xmom_explicit_update[k]=0.0;
-    ymom_explicit_update[k]=0.0;  
-  }
-
+  memset((char*) stage_explicit_update, 0, number_of_elements*sizeof(double));
+  memset((char*) xmom_explicit_update, 0, number_of_elements*sizeof(double));
+  memset((char*) ymom_explicit_update, 0, number_of_elements*sizeof(double));    
+  
   // For all triangles
-  for (k=0; k<number_of_elements; k++) {
-    
+  for (k = 0; k < number_of_elements; k++) 
+  {  
     // Loop through neighbours and compute edge flux for each  
-    for (i=0; i<3; i++) {
-      ki = k*3+i; // Linear index (triangle k, edge i)
+    for (i = 0; i < 3; i++) 
+    {
+      ki = k*3 + i; // Linear index to edge i of triangle k
       
       if (already_computed_flux[ki] == call)
+      {
         // We've already computed the flux across this edge
-	continue;
-	
-	
+        continue;
+      }
+    
+      // Get left hand side values from triangle k, edge i 
       ql[0] = stage_edge_values[ki];
       ql[1] = xmom_edge_values[ki];
@@ -1718,45 +1845,53 @@
       zl = bed_edge_values[ki];
 
-      // Quantities at neighbour on nearest face
+      // Get right hand side values either from neighbouring triangle
+      // or from boundary array (Quantities at neighbour on nearest face).
       n = neighbours[ki];
-      if (n < 0) {
+      if (n < 0) 
+      {
         // Neighbour is a boundary condition
-	m = -n-1; // Convert negative flag to boundary index
-	
-	qr[0] = stage_boundary_values[m];
-	qr[1] = xmom_boundary_values[m];
-	qr[2] = ymom_boundary_values[m];
-	zr = zl; // Extend bed elevation to boundary
-      } else {
-        // Neighbour is a real element
-	m = neighbour_edges[ki];
-	nm = n*3+m; // Linear index (triangle n, edge m)
-	
-	qr[0] = stage_edge_values[nm];
-	qr[1] = xmom_edge_values[nm];
-	qr[2] = ymom_edge_values[nm];
-	zr = bed_edge_values[nm];
-      }
-      
-      
-      if (optimise_dry_cells) {      
-	// Check if flux calculation is necessary across this edge
-	// This check will exclude dry cells.
-	// This will also optimise cases where zl != zr as 
-	// long as both are dry
-
-	if ( fabs(ql[0] - zl) < epsilon && 
-	     fabs(qr[0] - zr) < epsilon ) {
-	  // Cell boundary is dry
-	  
-	  already_computed_flux[ki] = call; // #k Done	
-	  if (n>=0)
-	    already_computed_flux[nm] = call; // #n Done
-	
-	  max_speed = 0.0;
-	  continue;
-	}
-      }
-    
+        m = -n - 1; // Convert negative flag to boundary index
+    
+        qr[0] = stage_boundary_values[m];
+        qr[1] = xmom_boundary_values[m];
+        qr[2] = ymom_boundary_values[m];
+        zr = zl; // Extend bed elevation to boundary
+      } 
+      else 
+      {
+        // Neighbour is a real triangle
+        m = neighbour_edges[ki];
+        nm = n*3 + m; // Linear index (triangle n, edge m)
+        
+        qr[0] = stage_edge_values[nm];
+        qr[1] = xmom_edge_values[nm];
+        qr[2] = ymom_edge_values[nm];
+        zr = bed_edge_values[nm];
+      }
+      
+      // Now we have values for this edge - both from left and right side.
+      
+      if (optimise_dry_cells) 
+      {     
+        // Check if flux calculation is necessary across this edge
+        // This check will exclude dry cells.
+        // This will also optimise cases where zl != zr as 
+        // long as both are dry
+
+        if (fabs(ql[0] - zl) < epsilon && 
+            fabs(qr[0] - zr) < epsilon) 
+        {
+          // Cell boundary is dry
+          
+          already_computed_flux[ki] = call; // #k Done  
+          if (n >= 0)
+          {
+            already_computed_flux[nm] = call; // #n Done
+          }
+        
+          max_speed = 0.0;
+          continue;
+        }
+      }
       
       // Outward pointing normal vector (domain.normals[k, 2*i:2*i+2])
@@ -1765,7 +1900,7 @@
       // Edge flux computation (triangle k, edge i)
       _flux_function_central(ql, qr, zl, zr,
-			     normals[ki2], normals[ki2+1],
-			     epsilon, H0, g,
-			     edgeflux, &max_speed);
+                             normals[ki2], normals[ki2+1],
+                             epsilon, H0, g,
+                             edgeflux, &max_speed);
       
       
@@ -1786,33 +1921,36 @@
       
       // Update neighbour n with same flux but reversed sign
-      if (n>=0) {
-	stage_explicit_update[n] += edgeflux[0];
-	xmom_explicit_update[n] += edgeflux[1];
-	ymom_explicit_update[n] += edgeflux[2];
-	
-	already_computed_flux[nm] = call; // #n Done
-      }
-
+      if (n >= 0) 
+      {
+        stage_explicit_update[n] += edgeflux[0];
+        xmom_explicit_update[n] += edgeflux[1];
+        ymom_explicit_update[n] += edgeflux[2];
+        
+        already_computed_flux[nm] = call; // #n Done
+      }
 
       // Update timestep based on edge i and possibly neighbour n
-      if (tri_full_flag[k] == 1) {
-	if (max_speed > epsilon) {
-	
-	  // Apply CFL condition for triangles joining this edge (triangle k and triangle n)
-	  
-	  // CFL for triangle k
-	  timestep = min(timestep, radii[k]/max_speed);
-	  
-	  if (n>=0) 
-	    // Apply CFL condition for neigbour n (which is on the ith edge of triangle k)
-	    timestep = min(timestep, radii[n]/max_speed);
-	  
-	  // Ted Rigby's suggested less conservative version
-	  //if (n>=0) { 	    
-	  //  timestep = min(timestep, (radii[k]+radii[n])/max_speed);
-	  //} else {
-	  //  timestep = min(timestep, radii[k]/max_speed);
-	  // }
-	}
+      if (tri_full_flag[k] == 1) 
+      {
+        if (max_speed > epsilon) 
+        {
+          // Apply CFL condition for triangles joining this edge (triangle k and triangle n)
+          
+          // CFL for triangle k
+          timestep = min(timestep, radii[k]/max_speed);
+          
+          if (n >= 0)
+          {
+            // Apply CFL condition for neigbour n (which is on the ith edge of triangle k)
+            timestep = min(timestep, radii[n]/max_speed);
+          }
+
+          // Ted Rigby's suggested less conservative version
+          //if (n>=0) {         
+          //  timestep = min(timestep, (radii[k]+radii[n])/max_speed);
+          //} else {
+          //  timestep = min(timestep, radii[k]/max_speed);
+          // }
+        }
       }
       
@@ -1822,8 +1960,8 @@
     // Normalise triangle k by area and store for when all conserved
     // quantities get updated
-    area = areas[k];
-    stage_explicit_update[k] /= area;
-    xmom_explicit_update[k] /= area;
-    ymom_explicit_update[k] /= area;
+    inv_area = 1.0/areas[k];
+    stage_explicit_update[k] *= inv_area;
+    xmom_explicit_update[k] *= inv_area;
+    ymom_explicit_update[k] *= inv_area;
     
    
@@ -1832,7 +1970,5 @@
     
   } // End triangle k
-	
-			       
-			       
+             
   return timestep;
 }
@@ -1869,30 +2005,30 @@
 
     PyObject 
-	*domain,
-	*stage, 
-	*xmom, 
-	*ymom, 
-	*bed;
+    *domain,
+    *stage, 
+    *xmom, 
+    *ymom, 
+    *bed;
 
     PyArrayObject 
-	*neighbours, 
-	*neighbour_edges,
-	*normals, 
-	*edgelengths, 
-	*radii, 
-	*areas,
-	*tri_full_flag,
-	*stage_edge_values,
-	*xmom_edge_values,
-	*ymom_edge_values,
-	*bed_edge_values,
-	*stage_boundary_values,
-	*xmom_boundary_values,
-	*ymom_boundary_values,
-	*stage_explicit_update,
-	*xmom_explicit_update,
-	*ymom_explicit_update,
-	*already_computed_flux, //Tracks whether the flux across an edge has already been computed
-	*max_speed_array; //Keeps track of max speeds for each triangle
+    *neighbours, 
+    *neighbour_edges,
+    *normals, 
+    *edgelengths, 
+    *radii, 
+    *areas,
+    *tri_full_flag,
+    *stage_edge_values,
+    *xmom_edge_values,
+    *ymom_edge_values,
+    *bed_edge_values,
+    *stage_boundary_values,
+    *xmom_boundary_values,
+    *ymom_boundary_values,
+    *stage_explicit_update,
+    *xmom_explicit_update,
+    *ymom_explicit_update,
+    *already_computed_flux, //Tracks whether the flux across an edge has already been computed
+    *max_speed_array; //Keeps track of max speeds for each triangle
 
     
@@ -1902,6 +2038,6 @@
     // Convert Python arguments to C
     if (!PyArg_ParseTuple(args, "dOOOO", &timestep, &domain, &stage, &xmom, &ymom, &bed )) {
-	PyErr_SetString(PyExc_RuntimeError, "Input arguments failed");
-	return NULL;
+    PyErr_SetString(PyExc_RuntimeError, "Input arguments failed");
+    return NULL;
     }
 
@@ -1940,28 +2076,28 @@
   // the explicit update arrays 
   timestep = _compute_fluxes_central(number_of_elements,
-				     timestep,
-				     epsilon,
-				     H0,
-				     g,
-				     (long*) neighbours -> data,
-				     (long*) neighbour_edges -> data,
-				     (double*) normals -> data,
-				     (double*) edgelengths -> data, 
-				     (double*) radii -> data, 
-				     (double*) areas -> data,
-				     (long*) tri_full_flag -> data,
-				     (double*) stage_edge_values -> data,
-				     (double*) xmom_edge_values -> data,
-				     (double*) ymom_edge_values -> data,
-				     (double*) bed_edge_values -> data,
-				     (double*) stage_boundary_values -> data,
-				     (double*) xmom_boundary_values -> data,
-				     (double*) ymom_boundary_values -> data,
-				     (double*) stage_explicit_update -> data,
-				     (double*) xmom_explicit_update -> data,
-				     (double*) ymom_explicit_update -> data,
-				     (long*) already_computed_flux -> data,
-				     (double*) max_speed_array -> data,
-				     optimise_dry_cells);
+                     timestep,
+                     epsilon,
+                     H0,
+                     g,
+                     (long*) neighbours -> data,
+                     (long*) neighbour_edges -> data,
+                     (double*) normals -> data,
+                     (double*) edgelengths -> data, 
+                     (double*) radii -> data, 
+                     (double*) areas -> data,
+                     (long*) tri_full_flag -> data,
+                     (double*) stage_edge_values -> data,
+                     (double*) xmom_edge_values -> data,
+                     (double*) ymom_edge_values -> data,
+                     (double*) bed_edge_values -> data,
+                     (double*) stage_boundary_values -> data,
+                     (double*) xmom_boundary_values -> data,
+                     (double*) ymom_boundary_values -> data,
+                     (double*) stage_explicit_update -> data,
+                     (double*) xmom_explicit_update -> data,
+                     (double*) ymom_explicit_update -> data,
+                     (long*) already_computed_flux -> data,
+                     (double*) max_speed_array -> data,
+                     optimise_dry_cells);
 
   Py_DECREF(neighbours);
@@ -2013,5 +2149,5 @@
     domain.timestep = compute_fluxes(timestep,
                                      domain.epsilon,
-				     domain.H0,
+                     domain.H0,
                                      domain.g,
                                      domain.neighbours,
@@ -2033,5 +2169,5 @@
                                      Ymom.explicit_update,
                                      already_computed_flux,
-				     optimise_dry_cells)				     
+                     optimise_dry_cells)                     
 
 
@@ -2066,26 +2202,26 @@
   // Convert Python arguments to C
   if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOOOi",
-			&timestep,
-			&epsilon,
-			&H0,
-			&g,
-			&neighbours,
-			&neighbour_edges,
-			&normals,
-			&edgelengths, &radii, &areas,
-			&tri_full_flag,
-			&stage_edge_values,
-			&xmom_edge_values,
-			&ymom_edge_values,
-			&bed_edge_values,
-			&stage_boundary_values,
-			&xmom_boundary_values,
-			&ymom_boundary_values,
-			&stage_explicit_update,
-			&xmom_explicit_update,
-			&ymom_explicit_update,
-			&already_computed_flux,
-			&max_speed_array,
-			&optimise_dry_cells)) {
+            &timestep,
+            &epsilon,
+            &H0,
+            &g,
+            &neighbours,
+            &neighbour_edges,
+            &normals,
+            &edgelengths, &radii, &areas,
+            &tri_full_flag,
+            &stage_edge_values,
+            &xmom_edge_values,
+            &ymom_edge_values,
+            &bed_edge_values,
+            &stage_boundary_values,
+            &xmom_boundary_values,
+            &ymom_boundary_values,
+            &stage_explicit_update,
+            &xmom_explicit_update,
+            &ymom_explicit_update,
+            &already_computed_flux,
+            &max_speed_array,
+            &optimise_dry_cells)) {
     PyErr_SetString(PyExc_RuntimeError, "Input arguments failed");
     return NULL;
@@ -2118,28 +2254,28 @@
   // the explicit update arrays 
   timestep = _compute_fluxes_central(number_of_elements,
-				     timestep,
-				     epsilon,
-				     H0,
-				     g,
-				     (long*) neighbours -> data,
-				     (long*) neighbour_edges -> data,
-				     (double*) normals -> data,
-				     (double*) edgelengths -> data, 
-				     (double*) radii -> data, 
-				     (double*) areas -> data,
-				     (long*) tri_full_flag -> data,
-				     (double*) stage_edge_values -> data,
-				     (double*) xmom_edge_values -> data,
-				     (double*) ymom_edge_values -> data,
-				     (double*) bed_edge_values -> data,
-				     (double*) stage_boundary_values -> data,
-				     (double*) xmom_boundary_values -> data,
-				     (double*) ymom_boundary_values -> data,
-				     (double*) stage_explicit_update -> data,
-				     (double*) xmom_explicit_update -> data,
-				     (double*) ymom_explicit_update -> data,
-				     (long*) already_computed_flux -> data,
-				     (double*) max_speed_array -> data,
-				     optimise_dry_cells);
+                     timestep,
+                     epsilon,
+                     H0,
+                     g,
+                     (long*) neighbours -> data,
+                     (long*) neighbour_edges -> data,
+                     (double*) normals -> data,
+                     (double*) edgelengths -> data, 
+                     (double*) radii -> data, 
+                     (double*) areas -> data,
+                     (long*) tri_full_flag -> data,
+                     (double*) stage_edge_values -> data,
+                     (double*) xmom_edge_values -> data,
+                     (double*) ymom_edge_values -> data,
+                     (double*) bed_edge_values -> data,
+                     (double*) stage_boundary_values -> data,
+                     (double*) xmom_boundary_values -> data,
+                     (double*) ymom_boundary_values -> data,
+                     (double*) stage_explicit_update -> data,
+                     (double*) xmom_explicit_update -> data,
+                     (double*) ymom_explicit_update -> data,
+                     (long*) already_computed_flux -> data,
+                     (double*) max_speed_array -> data,
+                     optimise_dry_cells);
   
   // Return updated flux timestep
@@ -2228,24 +2364,24 @@
   // Convert Python arguments to C
   if (!PyArg_ParseTuple(args, "ddddOOOOOOOOOOOOOOOOOO",
-			&timestep,
-			&epsilon,
-			&H0,
-			&g,
-			&neighbours,
-			&neighbour_edges,
-			&normals,
-			&edgelengths, &radii, &areas,
-			&tri_full_flag,
-			&stage_edge_values,
-			&xmom_edge_values,
-			&ymom_edge_values,
-			&bed_edge_values,
-			&stage_boundary_values,
-			&xmom_boundary_values,
-			&ymom_boundary_values,
-			&stage_explicit_update,
-			&xmom_explicit_update,
-			&ymom_explicit_update,
-			&already_computed_flux)) {
+            &timestep,
+            &epsilon,
+            &H0,
+            &g,
+            &neighbours,
+            &neighbour_edges,
+            &normals,
+            &edgelengths, &radii, &areas,
+            &tri_full_flag,
+            &stage_edge_values,
+            &xmom_edge_values,
+            &ymom_edge_values,
+            &bed_edge_values,
+            &stage_boundary_values,
+            &xmom_boundary_values,
+            &ymom_boundary_values,
+            &stage_explicit_update,
+            &xmom_explicit_update,
+            &ymom_explicit_update,
+            &already_computed_flux)) {
     PyErr_SetString(PyExc_RuntimeError, "Input arguments failed");
     return NULL;
@@ -2265,5 +2401,5 @@
       ki = k*3+i;
       if (((long *) already_computed_flux->data)[ki]==call)//we've already computed the flux across this edge
-	continue;
+    continue;
       ql[0] = ((double *) stage_edge_values -> data)[ki];
       ql[1] = ((double *) xmom_edge_values -> data)[ki];
@@ -2274,16 +2410,16 @@
       n = ((long *) neighbours -> data)[ki];
       if (n < 0) {
-	m = -n-1; //Convert negative flag to index
-	qr[0] = ((double *) stage_boundary_values -> data)[m];
-	qr[1] = ((double *) xmom_boundary_values -> data)[m];
-	qr[2] = ((double *) ymom_boundary_values -> data)[m];
-	zr = zl; //Extend bed elevation to boundary
+    m = -n-1; //Convert negative flag to index
+    qr[0] = ((double *) stage_boundary_values -> data)[m];
+    qr[1] = ((double *) xmom_boundary_values -> data)[m];
+    qr[2] = ((double *) ymom_boundary_values -> data)[m];
+    zr = zl; //Extend bed elevation to boundary
       } else {
-	m = ((long *) neighbour_edges -> data)[ki];
-	nm = n*3+m;
-	qr[0] = ((double *) stage_edge_values -> data)[nm];
-	qr[1] = ((double *) xmom_edge_values -> data)[nm];
-	qr[2] = ((double *) ymom_edge_values -> data)[nm];
-	zr =    ((double *) bed_edge_values -> data)[nm];
+    m = ((long *) neighbour_edges -> data)[ki];
+    nm = n*3+m;
+    qr[0] = ((double *) stage_edge_values -> data)[nm];
+    qr[1] = ((double *) xmom_edge_values -> data)[nm];
+    qr[2] = ((double *) ymom_edge_values -> data)[nm];
+    zr =    ((double *) bed_edge_values -> data)[nm];
       }
       // Outward pointing normal vector
@@ -2294,7 +2430,7 @@
       //Edge flux computation
       flux_function_kinetic(ql, qr, zl, zr,
-		    normal[0], normal[1],
-		    epsilon, H0, g,
-		    edgeflux, &max_speed);
+            normal[0], normal[1],
+            epsilon, H0, g,
+            edgeflux, &max_speed);
       //update triangle k
       ((long *) already_computed_flux->data)[ki]=call;
@@ -2304,22 +2440,22 @@
       //update the neighbour n
       if (n>=0){
-	((long *) already_computed_flux->data)[nm]=call;
-	((double *) stage_explicit_update -> data)[n] += edgeflux[0]*((double *) edgelengths -> data)[nm];
-	((double *) xmom_explicit_update -> data)[n] += edgeflux[1]*((double *) edgelengths -> data)[nm];
-	((double *) ymom_explicit_update -> data)[n] += edgeflux[2]*((double *) edgelengths -> data)[nm];
+    ((long *) already_computed_flux->data)[nm]=call;
+    ((double *) stage_explicit_update -> data)[n] += edgeflux[0]*((double *) edgelengths -> data)[nm];
+    ((double *) xmom_explicit_update -> data)[n] += edgeflux[1]*((double *) edgelengths -> data)[nm];
+    ((double *) ymom_explicit_update -> data)[n] += edgeflux[2]*((double *) edgelengths -> data)[nm];
       }
       ///for (j=0; j<3; j++) {
-	///flux[j] -= edgeflux[j]*((double *) edgelengths -> data)[ki];
-	///}
-	//Update timestep
-	//timestep = min(timestep, domain.radii[k]/max_speed)
-	//FIXME: SR Add parameter for CFL condition
+    ///flux[j] -= edgeflux[j]*((double *) edgelengths -> data)[ki];
+    ///}
+    //Update timestep
+    //timestep = min(timestep, domain.radii[k]/max_speed)
+    //FIXME: SR Add parameter for CFL condition
     if ( ((long *) tri_full_flag -> data)[k] == 1) {
-	    if (max_speed > epsilon) {
-	        timestep = min(timestep, ((double *) radii -> data)[k]/max_speed);
-	        //maxspeed in flux_function is calculated as max(|u+a|,|u-a|)
-	        if (n>=0)
-	            timestep = min(timestep, ((double *) radii -> data)[n]/max_speed);
-	    }
+        if (max_speed > epsilon) {
+            timestep = min(timestep, ((double *) radii -> data)[k]/max_speed);
+            //maxspeed in flux_function is calculated as max(|u+a|,|u-a|)
+            if (n>=0)
+                timestep = min(timestep, ((double *) radii -> data)[n]/max_speed);
+        }
     }
     } // end for i
@@ -2350,8 +2486,8 @@
   // Convert Python arguments to C
   if (!PyArg_ParseTuple(args, "dddOOOO",
-			&minimum_allowed_height,
-			&maximum_allowed_speed,
-			&epsilon,
-			&wc, &zc, &xmomc, &ymomc)) {
+            &minimum_allowed_height,
+            &maximum_allowed_speed,
+            &epsilon,
+            &wc, &zc, &xmomc, &ymomc)) {
     PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: protect could not parse input arguments");
     return NULL;
@@ -2361,11 +2497,11 @@
 
   _protect(N,
-	   minimum_allowed_height,
-	   maximum_allowed_speed,
-	   epsilon,
-	   (double*) wc -> data,
-	   (double*) zc -> data,
-	   (double*) xmomc -> data,
-	   (double*) ymomc -> data);
+       minimum_allowed_height,
+       maximum_allowed_speed,
+       epsilon,
+       (double*) wc -> data,
+       (double*) zc -> data,
+       (double*) xmomc -> data,
+       (double*) ymomc -> data);
 
   return Py_BuildValue("");
@@ -2409,14 +2545,14 @@
   // Convert Python arguments to C
   if (!PyArg_ParseTuple(args, "OOOOOOOOOO",
-			&domain,
-			&wc, &zc, 
-			&wv, &zv, &hvbar,
-			&xmomc, &ymomc, &xmomv, &ymomv)) {
+            &domain,
+            &wc, &zc, 
+            &wv, &zv, &hvbar,
+            &xmomc, &ymomc, &xmomv, &ymomv)) {
     PyErr_SetString(PyExc_RuntimeError, 
-		    "shallow_water_ext.c: balance_deep_and_shallow could not parse input arguments");
+            "shallow_water_ext.c: balance_deep_and_shallow could not parse input arguments");
     return NULL;
   }  
-	  
-	  
+      
+      
   // FIXME (Ole): I tested this without GetAttrString and got time down
   // marginally from 4.0s to 3.8s. Consider passing everything in 
@@ -2463,17 +2599,17 @@
   N = wc -> dimensions[0];
   _balance_deep_and_shallow(N,
-			    (double*) wc -> data,
-			    (double*) zc -> data,
-			    (double*) wv -> data,
-			    (double*) zv -> data,
-			    (double*) hvbar -> data,
-			    (double*) xmomc -> data,
-			    (double*) ymomc -> data,
-			    (double*) xmomv -> data,
-			    (double*) ymomv -> data,
-			    H0,
-			    (int) tight_slope_limiters,
-			    (int) use_centroid_velocities,			    
-			    alpha_balance);
+                (double*) wc -> data,
+                (double*) zc -> data,
+                (double*) wv -> data,
+                (double*) zv -> data,
+                (double*) hvbar -> data,
+                (double*) xmomc -> data,
+                (double*) ymomc -> data,
+                (double*) xmomv -> data,
+                (double*) ymomv -> data,
+                H0,
+                (int) tight_slope_limiters,
+                (int) use_centroid_velocities,              
+                alpha_balance);
 
 
@@ -2503,21 +2639,21 @@
   // Convert Python arguments to C
   if (!PyArg_ParseTuple(args, "OOOOd",
-			&xmom_update,
-			&ymom_update,
-			&s_vec, &phi_vec,
-			&cw)) {
+            &xmom_update,
+            &ymom_update,
+            &s_vec, &phi_vec,
+            &cw)) {
     PyErr_SetString(PyExc_RuntimeError, "shallow_water_ext.c: assign_windfield_values could not parse input arguments");
     return NULL;
   }  
-			
+            
 
   N = xmom_update -> dimensions[0];
 
   _assign_wind_field_values(N,
-	   (double*) xmom_update -> data,
-	   (double*) ymom_update -> data,
-	   (double*) s_vec -> data,
-	   (double*) phi_vec -> data,
-	   cw);
+       (double*) xmom_update -> data,
+       (double*) ymom_update -> data,
+       (double*) s_vec -> data,
+       (double*) phi_vec -> data,
+       cw);
 
   return Py_BuildValue("");
Index: /branches/numpy/anuga/shallow_water/test_data_manager.py
===================================================================
--- /branches/numpy/anuga/shallow_water/test_data_manager.py	(revision 6901)
+++ /branches/numpy/anuga/shallow_water/test_data_manager.py	(revision 6902)
@@ -15,4 +15,5 @@
 from struct import pack, unpack
 from sets import ImmutableSet
+import shutil
 
 from anuga.shallow_water import *
@@ -47,12 +48,12 @@
         
         self.verbose = Test_Data_Manager.verbose
-        #Create basic mesh
+        # Create basic mesh
         points, vertices, boundary = rectangular(2, 2)
 
-        #Create shallow water domain
+        # Create shallow water domain
         domain = Domain(points, vertices, boundary)
         domain.default_order = 2
 
-        #Set some field values
+        # Set some field values
         domain.set_quantity('elevation', lambda x,y: -x)
         domain.set_quantity('friction', 0.03)
@@ -252,25 +253,25 @@
 
         # Get the variables
-        #range = fid.variables['stage_range'][:]
+        range = fid.variables['stage_range'][:]
         #print range
-        #assert num.allclose(range,[-0.93519, 0.15]) or\
-        #       num.allclose(range,[-0.9352743, 0.15]) or\
-        #       num.allclose(range,[-0.93522203, 0.15000001]) # Old slope limiters
-        
-        #range = fid.variables['xmomentum_range'][:]
+        assert num.allclose(range,[-0.93519, 0.15]) or\
+               num.allclose(range,[-0.9352743, 0.15]) or\
+               num.allclose(range,[-0.93522203, 0.15000001]) # Old slope limiters
+        
+        range = fid.variables['xmomentum_range'][:]
         ##print range
-        #assert num.allclose(range,[0,0.4695096]) or \
-        #       num.allclose(range,[0,0.47790655]) or\
-        #       num.allclose(range,[0,0.46941957]) or\
-        #       num.allclose(range,[0,0.47769409])
-
-        
-        #range = fid.variables['ymomentum_range'][:]
+        assert num.allclose(range,[0,0.4695096]) or \
+               num.allclose(range,[0,0.47790655]) or\
+               num.allclose(range,[0,0.46941957]) or\
+               num.allclose(range,[0,0.47769409])
+
+        
+        range = fid.variables['ymomentum_range'][:]
         ##print range
-        #assert num.allclose(range,[0,0.02174380]) or\
-        #       num.allclose(range,[0,0.02174439]) or\
-        #       num.allclose(range,[0,0.02283983]) or\
-        #       num.allclose(range,[0,0.0217342]) or\
-        #       num.allclose(range,[0,0.0227564]) # Old slope limiters 
+        assert num.allclose(range,[0,0.02174380]) or\
+               num.allclose(range,[0,0.02174439]) or\
+               num.allclose(range,[0,0.02283983]) or\
+               num.allclose(range,[0,0.0217342]) or\
+               num.allclose(range,[0,0.0227564]) # Old slope limiters 
         
         fid.close()
@@ -1232,5 +1233,5 @@
         from Scientific.IO.NetCDF import NetCDFFile
 
-        #Setup
+        # Setup
         self.domain.set_name('datatest')
 
@@ -1245,5 +1246,5 @@
         self.domain.set_quantity('stage', 1.0)
 
-        self.domain.geo_reference = Geo_reference(56,308500,6189000)
+        self.domain.geo_reference = Geo_reference(56, 308500, 6189000)
 
         sww = get_dataobject(self.domain)
@@ -5563,5 +5564,5 @@
             quantities_init[0].append(this_ha) # HA
             quantities_init[1].append(this_ua) # UA
-            quantities_init[2].append(this_va) # VA
+            quantities_init[2].append(this_va) # VA 
                 
         file_handle, base_name = tempfile.mkstemp("")
@@ -6104,5 +6105,4 @@
                         #print 'writing', time, point_i, q_time[time, point_i]
                         f.write(pack('f', q_time[time, point_i]))
-
             f.close()
 
@@ -6215,9 +6215,9 @@
 
         msg='Incorrect gauge depths returned'
-        assert num.allclose(elevation,-depth),msg
+        assert num.allclose(elevation, -depth),msg
         msg='incorrect gauge height time series returned'
-        assert num.allclose(stage,ha)
+        assert num.allclose(stage, ha)
         msg='incorrect gauge ua time series returned'
-        assert num.allclose(xvelocity,ua)
+        assert num.allclose(xvelocity, ua)
         msg='incorrect gauge va time series returned'
         assert num.allclose(yvelocity, -va) # South is positive in MUX
@@ -6397,4 +6397,5 @@
                 if j == 2: assert num.allclose(data[i][:parameters_index], -va0[permutation[i], :])
         
+        self.delete_mux(filesI)
 
 
@@ -6407,5 +6408,6 @@
         wrong values Win32
 
-        This test does not pass on Windows but test_read_mux_platform_problem1 does
+        This test does not pass on Windows but test_read_mux_platform_problem1
+        does
         """
         
@@ -6422,5 +6424,6 @@
         times_ref = num.arange(0, time_step_count*time_step, time_step)
         
-        lat_long_points = [(-21.5,114.5), (-21,114.5), (-21.5,115), (-21.,115.), (-22., 117.)]
+        lat_long_points = [(-21.5,114.5), (-21,114.5), (-21.5,115),
+                           (-21.,115.), (-22., 117.)]
         n = len(lat_long_points)
         
@@ -6466,5 +6469,5 @@
              for j in range(0, first_tstep[i]-1) + range(last_tstep[i], time_step_count):
                  # For timesteps before and after recording range
-                 ha1[i][j] = ua1[i][j] = va1[i][j] = 0.0                                  
+                 ha1[i][j] = ua1[i][j] = va1[i][j] = 0.0 
 
 
@@ -6474,5 +6477,5 @@
         #print 'va', va1[0,:]
         
-        # Write second mux file to be combined by urs2sts                                             
+        # Write second mux file to be combined by urs2sts 
         base_nameII, filesII = self.write_mux2(lat_long_points,
                                                time_step_count, time_step,
@@ -6605,26 +6608,17 @@
 
             f.close()
-
-
-
-
-
-
-        
                                                
         # Create ordering file
         permutation = ensure_numeric([4,0,2])
 
-        _, ordering_filename = tempfile.mkstemp('')
-        order_fid = open(ordering_filename, 'w')  
-        order_fid.write('index, longitude, latitude\n')
-        for index in permutation:
-            order_fid.write('%d, %f, %f\n' %(index, 
-                                             lat_long_points[index][1], 
-                                             lat_long_points[index][0]))
-        order_fid.close()
-        
-        
-
+       #  _, ordering_filename = tempfile.mkstemp('')
+#         order_fid = open(ordering_filename, 'w')  
+#         order_fid.write('index, longitude, latitude\n')
+#         for index in permutation:
+#             order_fid.write('%d, %f, %f\n' %(index, 
+#                                              lat_long_points[index][1], 
+#                                              lat_long_points[index][0]))
+#         order_fid.close()
+        
         # -------------------------------------
         # Now read files back and check values
@@ -6638,6 +6632,4 @@
         for j, file in enumerate(filesII):
             # Read stage, u, v enumerated as j
-
-            
             #print 'Reading', j, file
             data = read_mux2(1, [file], weights, file_params, permutation, verbose)
@@ -6645,6 +6637,4 @@
             #print 'Data received by Python'
             #print data[1][8]
-
-            
             number_of_selected_stations = data.shape[0]
 
@@ -6659,6 +6649,4 @@
                 #print i, parameters_index
                 #print quantity[i][:]
-
-                
                 if j == 0: assert num.allclose(data[i][:parameters_index], ha1[permutation[i], :])
                 if j == 1: assert num.allclose(data[i][:parameters_index], ua1[permutation[i], :])
@@ -6669,13 +6657,305 @@
                     #print j, i
                     #print 'Input'
-                    #print 'u', ua1[permutation[i], 8]                                        
+                    #print 'u', ua1[permutation[i], 8]       
                     #print 'v', va1[permutation[i], 8]
                 
                     #print 'Output'
-                    #print 'v ', data[i][:parameters_index][8]                    
+                    #print 'v ', data[i][:parameters_index][8]  
+
+                    # South is positive in MUX
+                    #print "data[i][:parameters_index]", data[i][:parameters_index]
+                    #print "-va1[permutation[i], :]", -va1[permutation[i], :]
+                    assert num.allclose(data[i][:parameters_index], -va1[permutation[i], :])
+        
+        self.delete_mux(filesII)
+           
+    def test_read_mux_platform_problem3(self):
+        
+        # This is to test a situation where read_mux returned 
+        # wrong values Win32
+
+        
+        from urs_ext import read_mux2 
+        
+        from anuga.config import single_precision as epsilon        
+        
+        verbose = False
                 
-                    # South is positive in MUX
+        tide = 1.5
+        time_step_count = 10
+        time_step = 0.02
+
+        '''
+        Win results
+        time_step = 0.2000001
+        This is OK        
+        '''
+        
+        '''
+        Win results
+        time_step = 0.20000001
+
+        ======================================================================
+ERROR: test_read_mux_platform_problem3 (__main__.Test_Data_Manager)
+----------------------------------------------------------------------
+Traceback (most recent call last):
+  File "test_data_manager.py", line 6718, in test_read_mux_platform_problem3
+    ha1[0]=num.sin(times_ref)
+ValueError: matrices are not aligned for copy
+
+        '''
+
+        '''
+        Win results
+        time_step = 0.200000001
+        FAIL
+         assert num.allclose(data[i][:parameters_index],
+         -va1[permutation[i], :])
+        '''
+        times_ref = num.arange(0, time_step_count*time_step, time_step)
+        #print "times_ref", times_ref
+        
+        lat_long_points = [(-21.5,114.5), (-21,114.5), (-21.5,115),
+                           (-21.,115.), (-22., 117.)]
+        stations = len(lat_long_points)
+        
+        # Create different timeseries starting and ending at different times 
+        first_tstep=num.ones(stations, num.int)
+        first_tstep[0]+=2   # Point 0 starts at 2
+        first_tstep[1]+=4   # Point 1 starts at 4        
+        first_tstep[2]+=3   # Point 2 starts at 3
+        
+        last_tstep=(time_step_count)*num.ones(stations, num.int)
+        last_tstep[0]-=1    # Point 0 ends 1 step early
+        last_tstep[1]-=2    # Point 1 ends 2 steps early                
+        last_tstep[4]-=3    # Point 4 ends 3 steps early        
+        
+        # Create varying elevation data (positive values for seafloor)
+        gauge_depth=20*num.ones(stations, num.float)
+        for i in range(stations):
+            gauge_depth[i] += i**2
+            
+        # Create data to be written to second mux file        
+        ha1=num.ones((stations,time_step_count), num.float)
+        ha1[0]=num.sin(times_ref)
+        ha1[1]=2*num.sin(times_ref - 3)
+        ha1[2]=5*num.sin(4*times_ref)
+        ha1[3]=num.sin(times_ref)
+        ha1[4]=num.sin(2*times_ref-0.7)
+                
+        ua1=num.zeros((stations,time_step_count),num.float)
+        ua1[0]=3*num.cos(times_ref)        
+        ua1[1]=2*num.sin(times_ref-0.7)   
+        ua1[2]=num.arange(3*time_step_count,4*time_step_count)
+        ua1[4]=2*num.ones(time_step_count)
+        
+        va1=num.zeros((stations,time_step_count),num.float)
+        va1[0]=2*num.cos(times_ref-0.87)        
+        va1[1]=3*num.ones(time_step_count)
+        va1[3]=2*num.sin(times_ref-0.71)        
+        #print "va1[0]", va1[0]  # The 8th element is what will go bad.
+        # Ensure data used to write mux file to be zero when gauges are
+        # not recording
+        for i in range(stations):
+             # For each point
+             for j in range(0, first_tstep[i]-1) + range(last_tstep[i],
+                                                         time_step_count):
+                 # For timesteps before and after recording range
+                 ha1[i][j] = ua1[i][j] = va1[i][j] = 0.0 
+
+
+        #print 'Second station to be written to MUX'
+        #print 'ha', ha1[0,:]
+        #print 'ua', ua1[0,:]
+        #print 'va', va1[0,:]
+        
+        # Write second mux file to be combined by urs2sts 
+        base_nameII, filesII = self.write_mux2(lat_long_points,
+                                               time_step_count, time_step,
+                                               first_tstep, last_tstep,
+                                               depth=gauge_depth,
+                                               ha=ha1,
+                                               ua=ua1,
+                                               va=va1)
+        #print "filesII", filesII
+
+
+
+
+        # Read mux file back and verify it's correcness
+
+        ####################################################
+        # FIXME (Ole): This is where the test should
+        # verify that the MUX files are correct.
+
+        #JJ: It appears as though
+        #that certain quantities are not being stored with enough precision
+        #inn muxfile or more likely that they are being cast into a
+        #lower precision when read in using read_mux2 Time step and q_time
+        # are equal but only to approx 1e-7
+        ####################################################
+
+        #define information as it should be stored in mus2 files
+        points_num=len(lat_long_points)
+        depth=gauge_depth
+        ha=ha1
+        ua=ua1
+        va=va1
+        
+        quantities = ['HA','UA','VA']
+        mux_names = [WAVEHEIGHT_MUX2_LABEL,
+                     EAST_VELOCITY_MUX2_LABEL,
+                     NORTH_VELOCITY_MUX2_LABEL]
+        quantities_init = [[],[],[]]
+        latlondeps = []
+        #irrelevant header information
+        ig=ilon=ilat=0
+        mcolat=mcolon=centerlat=centerlon=offset=az=baz=id=0.0
+        # urs binary is latitude fastest
+        for i,point in enumerate(lat_long_points):
+            lat = point[0]
+            lon = point[1]
+            _ , e, n = redfearn(lat, lon)
+            if depth is None:
+                this_depth = n
+            else:
+                this_depth = depth[i]
+            latlondeps.append([lat, lon, this_depth])
+
+            if ha is None:
+                this_ha = e
+                quantities_init[0].append(num.ones(time_step_count,
+                                                   num.float)*this_ha) # HA
+            else:
+                quantities_init[0].append(ha[i])
+            if ua is None:
+                this_ua = n
+                quantities_init[1].append(num.ones(time_step_count,
+                                                   num.float)*this_ua) # UA
+            else:
+                quantities_init[1].append(ua[i])
+            if va is None:
+                this_va = e
+                quantities_init[2].append(num.ones(time_step_count,
+                                                   num.float)*this_va) #
+            else:
+                quantities_init[2].append(va[i])
+
+        for i, q in enumerate(quantities):
+            #print
+            #print i, q
+            
+            q_time = num.zeros((time_step_count, points_num), num.float)
+            quantities_init[i] = ensure_numeric(quantities_init[i])
+            for time in range(time_step_count):
+                #print i, q, time, quantities_init[i][:,time]
+                q_time[time,:] = quantities_init[i][:,time]
+                #print i, q, time, q_time[time, :]
+
+            
+            filename = base_nameII + mux_names[i]
+            f = open(filename, 'rb')
+            if self.verbose: print 'Reading' + filename
+            assert abs(points_num-unpack('i',f.read(4))[0])<epsilon
+            #write mux 2 header
+            for latlondep in latlondeps:
+                assert abs(latlondep[0]-unpack('f',f.read(4))[0])<epsilon
+                assert abs(latlondep[1]-unpack('f',f.read(4))[0])<epsilon
+                assert abs(mcolat-unpack('f',f.read(4))[0])<epsilon
+                assert abs(mcolon-unpack('f',f.read(4))[0])<epsilon
+                assert abs(ig-unpack('i',f.read(4))[0])<epsilon
+                assert abs(ilon-unpack('i',f.read(4))[0])<epsilon
+                assert abs(ilat-unpack('i',f.read(4))[0])<epsilon
+                assert abs(latlondep[2]-unpack('f',f.read(4))[0])<epsilon
+                assert abs(centerlat-unpack('f',f.read(4))[0])<epsilon
+                assert abs(centerlon-unpack('f',f.read(4))[0])<epsilon
+                assert abs(offset-unpack('f',f.read(4))[0])<epsilon
+                assert abs(az-unpack('f',f.read(4))[0])<epsilon
+                assert abs(baz-unpack('f',f.read(4))[0])<epsilon
+                
+                x = unpack('f', f.read(4))[0]
+                #print time_step
+                #print x
+                assert abs(time_step-x)<epsilon
+                assert abs(time_step_count-unpack('i',f.read(4))[0])<epsilon
+                for j in range(4): # identifier
+                    assert abs(id-unpack('i',f.read(4))[0])<epsilon 
+
+            #first_tstep=1
+            #last_tstep=time_step_count
+            for i,latlondep in enumerate(latlondeps):
+                assert abs(first_tstep[i]-unpack('i',f.read(4))[0])<epsilon
+            for i,latlondep in enumerate(latlondeps):
+                assert abs(last_tstep[i]-unpack('i',f.read(4))[0])<epsilon
+
+            # Find when first station starts recording
+            min_tstep = min(first_tstep)
+            # Find when all stations have stopped recording
+            max_tstep = max(last_tstep)
+
+            #for time in  range(time_step_count):
+            for time in range(min_tstep-1,max_tstep):
+                assert abs(time*time_step-unpack('f',f.read(4))[0])<epsilon
+                for point_i in range(points_num):
+                    if time+1>=first_tstep[point_i] and time+1<=last_tstep[point_i]:
+                        x = unpack('f',f.read(4))[0]
+                        #print time, x, q_time[time, point_i]
+                        if q == 'VA': x = -x # South is positive in MUX
+                        #print q+" q_time[%d, %d] = %f" %(time, point_i, 
+                                                      #q_time[time, point_i])
+                        assert abs(q_time[time, point_i]-x)<epsilon
+
+            f.close()
+                            
+        permutation = ensure_numeric([4,0,2])
+                   
+        # Create ordering file
+#         _, ordering_filename = tempfile.mkstemp('')
+#         order_fid = open(ordering_filename, 'w')  
+#         order_fid.write('index, longitude, latitude\n')
+#         for index in permutation:
+#             order_fid.write('%d, %f, %f\n' %(index, 
+#                                              lat_long_points[index][1], 
+#                                              lat_long_points[index][0]))
+#         order_fid.close()
+        
+        # -------------------------------------
+        # Now read files back and check values
+        weights = ensure_numeric([1.0])
+
+        # For each quantity read the associated list of source mux2 file with 
+        # extention associated with that quantity
+        file_params=-1*num.ones(3,num.float) # [nsta,dt,nt]
+        OFFSET = 5
+
+        for j, file in enumerate(filesII):
+            # Read stage, u, v enumerated as j
+            #print 'Reading', j, file
+            #print "file", file
+            data = read_mux2(1, [file], weights, file_params,
+                             permutation, verbose)
+            #print str(j) + "data", data
+
+            #print 'Data received by Python'
+            #print data[1][8]
+            number_of_selected_stations = data.shape[0]
+            #print "number_of_selected_stations", number_of_selected_stations
+            #print "stations", stations
+
+            # Index where data ends and parameters begin
+            parameters_index = data.shape[1]-OFFSET          
+                 
+            for i in range(number_of_selected_stations):
+        
+                #print i, parameters_index
+                if j == 0:
+                    assert num.allclose(data[i][:parameters_index],
+                                        ha1[permutation[i], :])
+                    
+                if j == 1: assert num.allclose(data[i][:parameters_index], ua1[permutation[i], :])
+                if j == 2:
                     assert num.allclose(data[i][:parameters_index], -va1[permutation[i], :])
-                    
+        
+        self.delete_mux(filesII)            
         
     def test_urs2sts0(self):
@@ -6819,10 +7099,10 @@
 
         base_name, files = self.write_mux2(lat_long_points,
-                                      time_step_count, time_step,
-                                      first_tstep, last_tstep,
-                                      depth=gauge_depth,
-                                      ha=ha,
-                                      ua=ua,
-                                      va=va)
+                                           time_step_count, time_step,
+                                           first_tstep, last_tstep,
+                                           depth=gauge_depth,
+                                           ha=ha,
+                                           ua=ua,
+                                           va=va)
 
         urs2sts(base_name,
@@ -6850,6 +7130,6 @@
         y = points[:,1]
 
-        #Check that all coordinate are correctly represented       
-        #Using the non standard projection (50) 
+        # Check that all coordinate are correctly represented       
+        # Using the non standard projection (50) 
         for i in range(4):
             zone, e, n = redfearn(lat_long_points[i][0],
@@ -6858,4 +7138,6 @@
             assert num.allclose([x[i],y[i]], [e,n])
             assert zone==-1
+        
+        self.delete_mux(files)
 
             
@@ -6915,6 +7197,6 @@
         y = points[:,1]
 
-        #Check that all coordinate are correctly represented       
-        #Using the non standard projection (50) 
+        # Check that all coordinate are correctly represented       
+        # Using the non standard projection (50) 
         for i in range(4):
             zone, e, n = redfearn(lat_long_points[i][0], lat_long_points[i][1],
@@ -6922,4 +7204,6 @@
             assert num.allclose([x[i],y[i]], [e,n])
             assert zone==geo_reference.zone
+        
+        self.delete_mux(files)
 
             
@@ -7652,4 +7936,7 @@
             raise Exception, msg
 
+        
+        self.delete_mux(filesI)
+        self.delete_mux(filesII)
 
         
@@ -8034,6 +8321,4 @@
         os.remove(sts_file)
         
-        
-        
         #----------------------
         # Then read the mux files together and test
@@ -8148,6 +8433,4 @@
         os.remove(sts_file)
         
-
-        
         #---------------
         # "Manually" add the timeseries up with weights and test
@@ -8157,9 +8440,4 @@
         stage_man = weights[0]*(stage0-tide) + weights[1]*(stage1-tide) + tide
         assert num.allclose(stage_man, stage)
-        
-        
-        
-        
-        
                 
         
@@ -8288,15 +8566,12 @@
                         
         assert num.allclose(domain_fbound.quantities['xmomentum'].vertex_values,
-                            domain_drchlt.quantities['xmomentum'].vertex_values)                        
+                            domain_drchlt.quantities['xmomentum'].vertex_values) 
                         
         assert num.allclose(domain_fbound.quantities['ymomentum'].vertex_values,
-                            domain_drchlt.quantities['ymomentum'].vertex_values)                                                
+                            domain_drchlt.quantities['ymomentum'].vertex_values)
         
         
         os.remove(sts_file+'.sts')
         os.remove(meshname)
-        
-        
-        
                 
         
@@ -8419,11 +8694,4 @@
 
 
-
-        
-        
-        
-            
-
-        
         domain_drchlt = Domain(meshname)
         domain_drchlt.set_quantity('stage', tide)
@@ -8447,15 +8715,11 @@
                         
         assert num.allclose(domain_fbound.quantities['xmomentum'].vertex_values,
-                            domain_drchlt.quantities['xmomentum'].vertex_values)                        
+                            domain_drchlt.quantities['xmomentum'].vertex_values) 
                         
         assert num.allclose(domain_fbound.quantities['ymomentum'].vertex_values,
-                            domain_drchlt.quantities['ymomentum'].vertex_values)                                                
-        
+                            domain_drchlt.quantities['ymomentum'].vertex_values) 
         
         os.remove(sts_file+'.sts')
         os.remove(meshname)
-
-
-        
                 
         
@@ -10934,4 +11198,5 @@
         domain.set_quantity('xmomentum', uh)
         domain.set_boundary( {'left': Bd, 'right': Bd, 'top': Br, 'bottom': Br})
+
         for t in domain.evolve(yieldstep=1, finaltime = t_end):
             pass
@@ -11357,4 +11622,47 @@
 
             
+    def test_copy_code_files(self):
+        '''test that the copy_code_files() function is sane.'''
+
+        def create_file(f):
+            fd = open(f, 'w')
+            fd.write('%s\n' % f)
+            fd.close()
+
+        # create working directories and test files
+        work_dir = tempfile.mkdtemp()
+        dst_dir = tempfile.mkdtemp(dir=work_dir)
+        src_dir = tempfile.mkdtemp(dir=work_dir)
+
+        f1 = 'file1'        
+        filename1 = os.path.join(src_dir, f1)
+        create_file(filename1)
+        f2 = 'file2'        
+        filename2 = os.path.join(src_dir, f2)
+        create_file(filename2)
+        f3 = 'file3'        
+        filename3 = os.path.join(src_dir, f3)
+        create_file(filename3)
+        f4 = 'file4'        
+        filename4 = os.path.join(src_dir, f4)
+        create_file(filename4)
+        f5 = 'file5'        
+        filename5 = os.path.join(src_dir, f5)
+        create_file(filename5)
+
+        # exercise the copy function
+        copy_code_files(dst_dir, filename1)
+        copy_code_files(dst_dir, filename1, filename2)
+        copy_code_files(dst_dir, (filename4, filename5, filename3))
+
+        # test that files were actually copied
+        self.failUnless(access(os.path.join(dst_dir, f1), F_OK))
+        self.failUnless(access(os.path.join(dst_dir, f2), F_OK))
+        self.failUnless(access(os.path.join(dst_dir, f3), F_OK))
+        self.failUnless(access(os.path.join(dst_dir, f4), F_OK))
+        self.failUnless(access(os.path.join(dst_dir, f5), F_OK))
+
+        # clean up
+        shutil.rmtree(work_dir)
             
 #-------------------------------------------------------------
@@ -11362,8 +11670,4 @@
 if __name__ == "__main__":
     suite = unittest.makeSuite(Test_Data_Manager,'test')
-
-    # FIXME (Ole): This is the test that fails under Windows
-    #suite = unittest.makeSuite(Test_Data_Manager,'test_read_mux_platform_problem2')
-    #suite = unittest.makeSuite(Test_Data_Manager,'test_file_boundary_stsIV')
     
     if len(sys.argv) > 1 and sys.argv[1][0].upper() == 'V':
Index: /branches/numpy/anuga/shallow_water/test_shallow_water_domain.py
===================================================================
--- /branches/numpy/anuga/shallow_water/test_shallow_water_domain.py	(revision 6901)
+++ /branches/numpy/anuga/shallow_water/test_shallow_water_domain.py	(revision 6902)
@@ -27,10 +27,8 @@
 def linear_function(point):
     point = num.array(point)
-    return point[:,0] + point[:,1]
-
+    return point[:,0]+point[:,1]
 
 class Weir:
     """Set a bathymetry for weir with a hole and a downstream gutter
-
     x,y are assumed to be in the unit square
     """
@@ -45,15 +43,15 @@
         z = num.zeros(N, num.float)
         for i in range(N):
-            z[i] = -x[i] / 2    # General slope
-
-            # Flattish bit to the left
+            z[i] = -x[i]/2  #General slope
+
+            #Flattish bit to the left
             if x[i] < 0.3:
                 z[i] = -x[i]/10
 
-            # Weir
+            #Weir
             if x[i] >= 0.3 and x[i] < 0.4:
                 z[i] = -x[i]+0.9
 
-            # Dip
+            #Dip
             x0 = 0.6
             depth = -1.0
@@ -62,34 +60,34 @@
                 if x[i] > x0 and x[i] < 0.9:
                     z[i] = depth
-                # RHS plateaux
+                #RHS plateaux
                 if x[i] >= 0.9:
                     z[i] = plateaux
             elif y[i] >= 0.7 and y[i] < 1.5:
-                # Restrict and deepen
+                #Restrict and deepen
                 if x[i] >= x0 and x[i] < 0.8:
                     z[i] = depth - (y[i]/3 - 0.3)
                 elif x[i] >= 0.8:
-                    # RHS plateaux
+                    #RHS plateaux
                     z[i] = plateaux
             elif y[i] >= 1.5:
                 if x[i] >= x0 and x[i] < 0.8 + (y[i]-1.5)/1.2:
-                    # Widen up and stay at constant depth
-                    z[i] = depth - 1.5/5
-                elif x[i] >= 0.8 + (y[i] - 1.5)/1.2:
-                    # RHS plateaux
+                    #Widen up and stay at constant depth
+                    z[i] = depth-1.5/5
+                elif x[i] >= 0.8 + (y[i]-1.5)/1.2:
+                    #RHS plateaux
                     z[i] = plateaux
 
-            # Hole in weir (slightly higher than inflow condition)
+            #Hole in weir (slightly higher than inflow condition)
             if x[i] >= 0.3 and x[i] < 0.4 and y[i] > 0.2 and y[i] < 0.4:
-                z[i] = -x[i] + self.inflow_stage + 0.02
-
-            # Channel behind weir
+                z[i] = -x[i]+self.inflow_stage + 0.02
+
+            #Channel behind weir
             x0 = 0.5
             if x[i] >= 0.4 and x[i] < x0 and y[i] > 0.2 and y[i] < 0.4:
-                z[i] = -x[i] + self.inflow_stage + 0.02
+                z[i] = -x[i]+self.inflow_stage + 0.02
 
             if x[i] >= x0 and x[i] < 0.6 and y[i] > 0.2 and y[i] < 0.4:
-                # Flatten it out towards the end
-                z[i] = -x0 + self.inflow_stage + 0.02 + (x0 - x[i])/5
+                #Flatten it out towards the end
+                z[i] = -x0+self.inflow_stage + 0.02 + (x0-x[i])/5
 
             # Hole to the east
@@ -97,12 +95,12 @@
             y0 = 0.35
             if num.sqrt((2*(x[i]-x0))**2 + (2*(y[i]-y0))**2) < 0.2:
-                z[i] = num.sqrt((x[i]-x0)**2 + (y[i]-y0)**2) - 1.0
-
-            # Tiny channel draining hole
+                z[i] = num.sqrt(((x[i]-x0))**2 + ((y[i]-y0))**2)-1.0
+
+            #Tiny channel draining hole
             if x[i] >= 1.14 and x[i] < 1.2 and y[i] >= 0.4 and y[i] < 0.6:
-                z[i] = -0.9    # North south
+                z[i] = -0.9 #North south
 
             if x[i] >= 0.9 and x[i] < 1.18 and y[i] >= 0.58 and y[i] < 0.65:
-                z[i] = -1.0 + (x[i]-0.9)/3    # East west
+                z[i] = -1.0 + (x[i]-0.9)/3 #East west
 
             # Stuff not in use
@@ -136,21 +134,22 @@
         z = num.zeros(N, num.float)
         for i in range(N):
-            z[i] = -x[i]    # General slope
-
-            # Flat bit to the left
+            z[i] = -x[i]  #General slope
+
+            #Flat bit to the left
             if x[i] < 0.3:
-                z[i] = -x[i]/10    # General slope
-
-            # Weir
+                z[i] = -x[i]/10  #General slope
+
+            #Weir
             if x[i] > 0.3 and x[i] < 0.4:
-                z[i] = -x[i] + 0.9
-
-            # Dip
+                z[i] = -x[i]+0.9
+
+            #Dip
             if x[i] > 0.6 and x[i] < 0.9:
-                z[i] = -x[i] - 0.5    # -y[i]/5
-
-            # Hole in weir (slightly higher than inflow condition)
+                z[i] = -x[i]-0.5  #-y[i]/5
+
+            #Hole in weir (slightly higher than inflow condition)
             if x[i] > 0.3 and x[i] < 0.4 and y[i] > 0.2 and y[i] < 0.4:
-                z[i] = -x[i] + self.inflow_stage + 0.05
+                z[i] = -x[i]+self.inflow_stage + 0.05
+
 
         return z/2
@@ -170,5 +169,5 @@
 
     N = len(x)
-    s = 0 * x    # New array
+    s = 0*x  #New array
 
     for k in range(N):
@@ -263,8 +262,8 @@
         H0 = 0.0
 
-        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux,
-                                  epsilon, g, H0)
-
-        assert num.allclose(edgeflux, [0, 0, 0])
+        
+        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)
+
+        assert num.allclose(edgeflux, [0,0,0])
         assert max_speed == 0.
 
@@ -272,5 +271,5 @@
         w = 2.0
 
-        normal = num.array([1., 0])
+        normal = num.array([1.,0])
         ql = num.array([w, 0, 0])
         qr = num.array([w, 0, 0])
@@ -280,7 +279,5 @@
         H0 = 0.0
 
-        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux,
-                                  epsilon, g, H0)
-
+        max_speed = flux_function(normal, ql, qr, zl, zr, edgeflux, epsilon, g, H0)        
         assert num.allclose(edgeflux, [0., 0.5*g*h**2, 0.])
         assert max_speed == num.sqrt(g*h)
@@ -290,5 +287,5 @@
     #    w = 2.0
     #
-    #    normal = array([1., 0])
+    #    normal = array([1.,0])
     #    ql = array([w, 0, 0])
     #    qr = array([w, 0, 0])
@@ -1517,6 +1514,7 @@
         uh = u*h
 
-        Br = Reflective_boundary(domain)       # Side walls
-        Bd = Dirichlet_boundary([w, uh, 0])    # 2 m/s across the 3 m inlet:
+        Br = Reflective_boundary(domain)     # Side walls
+        Bd = Dirichlet_boundary([w, uh, 0])  # 2 m/s across the 3 m inlet: 
+
 
         # Initial conditions
Index: /branches/numpy/anuga/shallow_water/urs_ext.c
===================================================================
--- /branches/numpy/anuga/shallow_water/urs_ext.c	(revision 6901)
+++ /branches/numpy/anuga/shallow_water/urs_ext.c	(revision 6902)
@@ -104,6 +104,6 @@
                 memcpy(data + it, muxData + offset, sizeof(float));
 		
-		//printf("%d: muxdata=%f\n", it, muxData[offset]);	    		
-		//printf("data[%d]=%f, offset=%d\n", it, data[it], offset);	    
+		//printf("%d: muxdata=%f\n", it, muxData[offset]); 
+		//printf("data[%d]=%f, offset=%d\n", it, data[it], offset); 
                 offset++;
             }
@@ -221,5 +221,5 @@
 
         // Open the mux file
-        if((fp = fopen(muxFileName, "r")) == NULL)
+        if((fp = fopen(muxFileName, "rb")) == NULL)
         {
             char *err_msg = strerror(errno);
@@ -237,5 +237,5 @@
 	    }
         
-            fros = (int*) malloc(*total_number_of_stations*numSrc*sizeof(int)); 
+            fros = (int*) malloc(*total_number_of_stations*numSrc*sizeof(int));
             lros = (int*) malloc(*total_number_of_stations*numSrc*sizeof(int));
       
@@ -447,5 +447,5 @@
     temp_sts_data = (float*) calloc(len_sts_data, sizeof(float));
 
-    muxData = (float*) malloc(numDataMax*sizeof(float));
+    muxData = (float*) calloc(numDataMax, sizeof(float));
     
     // Loop over all sources
@@ -460,5 +460,5 @@
         // Read in data block from mux2 file
         muxFileName = muxFileNameArray[isrc];
-        if((fp = fopen(muxFileName, "r")) == NULL)
+        if((fp = fopen(muxFileName, "rb")) == NULL)
         {
             fprintf(stderr, "cannot open file %s\n", muxFileName);
@@ -470,54 +470,22 @@
         }
 
-        offset = sizeof(int) + total_number_of_stations*(sizeof(struct tgsrwg) + 2*sizeof(int));
-        fseek(fp, offset, 0);
+        offset = (long int)sizeof(int) + total_number_of_stations*(sizeof(struct tgsrwg) + 2*sizeof(int));
+        //printf("\n offset %i ", (long int)offset);
+	fseek(fp, offset, 0);
 
         numData = getNumData(fros_per_source, 
 			     lros_per_source, 
 			     total_number_of_stations);
-			     
-			     
-        			     
-        elements_read = fread(muxData, ((int) numData)*sizeof(float), 1, fp); 
+	// Note numData is larger than what it has to be.		     
+        //elements_read = fread(muxData, ((int) numData)*sizeof(float), 1, fp); 
+        elements_read = fread(muxData, (size_t) sizeof(float), (size_t) numData, fp); 
+	//printf("\n elements_read  %d, ", (int)elements_read);
+	//printf("\n ferror(fp)  %d, ", (int)ferror(fp));
 	if ((int) elements_read == 0 && ferror(fp)) {
 	  fprintf(stderr, "Error reading mux data\n");
 	  return NULL;
-	}
-	 	
-        fclose(fp);
+	}	
 	
-
-	// FIXME (Ole): This is where Nariman and Ole traced the platform dependent 
-	// difference on 11 November 2008. We don't think the problem lies in the 
-	// C code. Maybe it is a problem with the MUX files written by the unit test
-	// that fails on Windows but works OK on Linux. JJ's test on 17th November shows
-	// that as far as Python is concerned this file should be OK on both platforms.
-	
-	
-	
-	// These printouts are enough to show the problem when compared 
-	// on the two platforms 
-	//printf("\nRead %d elements, ", (int) numData);
-	//printf("muxdata[%d]=%f\n", 39, muxData[39]);		
-	
-	
-	/*
-        In Windows we get
-	
-	Read 85 elements, muxdata[39]=0.999574
-	Read 85 elements, muxdata[39]=-0.087599
-	Read 85 elements, muxdata[39]=-0.087599
-	
-	
-	In Linux we get (the correct)
-	
-	Read 85 elements, muxdata[39]=0.999574
-	Read 85 elements, muxdata[39]=-0.087599
-	Read 85 elements, muxdata[39]=1.490349
-	*/
-	
-	
-	
-	
+        fclose(fp);  
 	
         // loop over stations present in the permutation array 
Index: /branches/numpy/anuga/utilities/log.py
===================================================================
--- /branches/numpy/anuga/utilities/log.py	(revision 6901)
+++ /branches/numpy/anuga/utilities/log.py	(revision 6902)
@@ -60,4 +60,8 @@
 NOTSET = logging.NOTSET
 
+# get True if python version 2.5 or later
+(version_major, version_minor, _, _, _) = sys.version_info
+new_python = ((version_major == 2 and version_minor >= 5) or version_major > 2)
+
 
 ################################################################################
@@ -79,7 +83,4 @@
     global _setup, log_logging_level
 
-    # get running python version for later
-    (version_major, version_minor, _, _, _) = sys.version_info
-
     # have we been setup?
     if not _setup:
@@ -89,5 +90,5 @@
 
         # setup the file logging system
-        if version_major >= 2 and version_minor >= 5:
+        if new_python:
             fmt = '%(asctime)s %(levelname)-8s %(mname)25s:%(lnum)-4d|%(message)s'
         else:
@@ -109,5 +110,5 @@
                         logging.getLevelName(log_logging_level),
                         logging.getLevelName(console_logging_level)))
-        if version_major >= 2 and version_minor >= 5:
+        if new_python:
             logging.log(logging.CRITICAL, start_msg,
                         extra={'mname': __name__, 'lnum': 0})
@@ -127,5 +128,5 @@
             break
 
-    if version_major >= 2 and version_minor >= 5:
+    if new_python:
         logging.log(level, msg, extra={'mname': fname, 'lnum': lnum})
     else:
@@ -139,5 +140,5 @@
 # @brief Shortcut for log(DEBUG, msg).
 # @param msg Message string to log at logging.DEBUG level.
-def debug(msg):
+def debug(msg=''):
     log(logging.DEBUG, msg)
 
@@ -145,5 +146,5 @@
 # @brief Shortcut for log(INFO, msg).
 # @param msg Message string to log at logging.INFO level.
-def info(msg):
+def info(msg=''):
     log(logging.INFO, msg)
 
@@ -151,5 +152,5 @@
 # @brief Shortcut for log(WARNING, msg).
 # @param msg Message string to log at logging.WARNING level.
-def warning(msg):
+def warning(msg=''):
     log(logging.WARNING, msg)
 
@@ -157,5 +158,5 @@
 # @brief Shortcut for log(ERROR, msg).
 # @param msg Message string to log at logging.ERROR level.
-def error(msg):
+def error(msg=''):
     log(logging.ERROR, msg)
 
@@ -163,5 +164,5 @@
 # @brief Shortcut for log(CRITICAL, msg).
 # @param msg Message string to log at logging.CRITICAL level.
-def critical(msg):
+def critical(msg=''):
     log(logging.CRITICAL, msg)
 
@@ -219,7 +220,2 @@
     else:
         pass
-
-if __name__ == "__main__":
-    debug('DEBUG message')
-    info('INFO message')
-    warning('WARNING message')
Index: /branches/numpy/anuga/utilities/log_test.py
===================================================================
--- /branches/numpy/anuga/utilities/log_test.py	(revision 6901)
+++ /branches/numpy/anuga/utilities/log_test.py	(revision 6902)
@@ -27,9 +27,8 @@
 
     def tearDown(self):
-        pass
-#        if os.path.exists(LOGFILE_NAME):
-#            os.remove(LOGFILE_NAME)
-#        if os.path.exists(STDOUT_LOG_NAME):
-#            os.remove(STDOUT_LOG_NAME)
+        if os.path.exists(LOGFILE_NAME):
+            os.remove(LOGFILE_NAME)
+        if os.path.exists(STDOUT_LOG_NAME):
+            os.remove(STDOUT_LOG_NAME)
 
     ##
