Index: /anuga_core/source/anuga/shallow_water/__init__.py
===================================================================
--- /anuga_core/source/anuga/shallow_water/__init__.py	(revision 7730)
+++ /anuga_core/source/anuga/shallow_water/__init__.py	(revision 7731)
@@ -7,19 +7,19 @@
 
 # Make selected classes available directly
-from shallow_water_domain import Domain,\
-     Transmissive_boundary, Reflective_boundary,\
-     Dirichlet_boundary, Time_boundary, File_boundary,\
+from boundaries import Reflective_boundary,\
      Transmissive_momentum_set_stage_boundary,\
      Dirichlet_discharge_boundary,\
      Field_boundary,\
      Transmissive_stage_zero_momentum_boundary,\
-     Transmissive_n_momentum_zero_t_momentum_set_stage_boundary,\
-     AWI_boundary
+     Transmissive_n_momentum_zero_t_momentum_set_stage_boundary
+
+from anuga.abstract_2d_finite_volumes.generic_boundary_conditions\
+     import Transmissive_boundary, Dirichlet_boundary, \
+            Time_boundary, File_boundary, AWI_boundary
+
+from shallow_water_domain import Domain
 
 #from shallow_water_balanced_domain import Swb_domain
 
 
-# FIXME (Ole): Deprecate
-from shallow_water_domain import Transmissive_Momentum_Set_Stage_boundary
-from shallow_water_domain import Dirichlet_Discharge_boundary
  
Index: /anuga_core/source/anuga/shallow_water/shallow_water_domain.py
===================================================================
--- /anuga_core/source/anuga/shallow_water/shallow_water_domain.py	(revision 7730)
+++ /anuga_core/source/anuga/shallow_water/shallow_water_domain.py	(revision 7731)
@@ -1213,547 +1213,4 @@
 
 
-################################################################################
-# Boundary conditions - specific to the shallow water wave equation
-################################################################################
-
-##
-# @brief Class for a reflective boundary.
-# @note Inherits from Boundary.
-class Reflective_boundary(Boundary):
-    """Reflective boundary returns same conserved quantities as
-    those present in its neighbour volume but reflected.
-
-    This class is specific to the shallow water equation as it
-    works with the momentum quantities assumed to be the second
-    and third conserved quantities.
-    """
-
-    ##
-    # @brief Instantiate a Reflective_boundary.
-    # @param domain 
-    def __init__(self, domain=None):
-        Boundary.__init__(self)
-
-        if domain is None:
-            msg = 'Domain must be specified for reflective boundary'
-            raise Exception, msg
-
-        # Handy shorthands
-        self.stage = domain.quantities['stage'].edge_values
-        self.xmom = domain.quantities['xmomentum'].edge_values
-        self.ymom = domain.quantities['ymomentum'].edge_values
-        self.normals = domain.normals
-
-        self.conserved_quantities = num.zeros(3, num.float)
-
-    ##
-    # @brief Return a representation of this instance.
-    def __repr__(self):
-        return 'Reflective_boundary'
-
-    ##
-    # @brief Calculate reflections (reverse outward momentum).
-    # @param vol_id 
-    # @param edge_id 
-    def evaluate(self, vol_id, edge_id):
-        """Reflective boundaries reverses the outward momentum
-        of the volume they serve.
-        """
-
-        q = self.conserved_quantities
-        q[0] = self.stage[vol_id, edge_id]
-        q[1] = self.xmom[vol_id, edge_id]
-        q[2] = self.ymom[vol_id, edge_id]
-
-        normal = self.normals[vol_id, 2*edge_id:2*edge_id+2]
-
-        r = rotate(q, normal, direction = 1)
-        r[1] = -r[1]
-        q = rotate(r, normal, direction = -1)
-
-        return q
-
-
-##
-# @brief Class for a transmissive boundary.
-# @note Inherits from Boundary.
-class Transmissive_momentum_set_stage_boundary(Boundary):
-    """Returns same momentum conserved quantities as
-    those present in its neighbour volume.
-    Sets stage by specifying a function f of time which may either be a
-    vector function or a scalar function
-
-    Example:
-
-    def waveform(t):
-        return sea_level + normalized_amplitude/cosh(t-25)**2
-
-    Bts = Transmissive_momentum_set_stage_boundary(domain, waveform)
-
-    Underlying domain must be specified when boundary is instantiated
-    """
-
-    ##
-    # @brief Instantiate a Transmissive_momentum_set_stage_boundary.
-    # @param domain
-    # @param function
-    def __init__(self, domain=None, function=None):
-        Boundary.__init__(self)
-
-        if domain is None:
-            msg = 'Domain must be specified for this type boundary'
-            raise Exception, msg
-
-        if function is None:
-            msg = 'Function must be specified for this type boundary'
-            raise Exception, msg
-
-        self.domain = domain
-        self.function = function
-
-    ##
-    # @brief Return a representation of this instance.
-    def __repr__(self):
-        return 'Transmissive_momentum_set_stage_boundary(%s)' %self.domain
-
-    ##
-    # @brief Calculate transmissive results.
-    # @param vol_id 
-    # @param edge_id 
-    def evaluate(self, vol_id, edge_id):
-        """Transmissive momentum set stage boundaries return the edge momentum
-        values of the volume they serve.
-        """
-
-        q = self.domain.get_conserved_quantities(vol_id, edge = edge_id)
-
-        t = self.domain.get_time()
-
-        if hasattr(self.function, 'time'):
-            # Roll boundary over if time exceeds
-            while t > self.function.time[-1]:
-                msg = 'WARNING: domain time %.2f has exceeded' % t
-                msg += 'time provided in '
-                msg += 'transmissive_momentum_set_stage_boundary object.\n'
-                msg += 'I will continue, reusing the object from t==0'
-                log.critical(msg)
-                t -= self.function.time[-1]
-
-        value = self.function(t)
-        try:
-            x = float(value)
-        except:
-            x = float(value[0])
-
-        q[0] = x
-           
-        return q
-
-        # FIXME: Consider this (taken from File_boundary) to allow
-        # spatial variation
-        # if vol_id is not None and edge_id is not None:
-        #     i = self.boundary_indices[ vol_id, edge_id ]
-        #     return self.F(t, point_id = i)
-        # else:
-        #     return self.F(t)
-
-
-##
-# @brief Deprecated boundary class.
-class Transmissive_Momentum_Set_Stage_boundary(Transmissive_momentum_set_stage_boundary):
-    pass
-
-
-##
-# @brief Class for a transmissive boundary.
-# @note Inherits from Boundary.
-class Transmissive_n_momentum_zero_t_momentum_set_stage_boundary(Boundary):
-    """Returns the same normal momentum as that 
-    present in neighbour volume edge. Zero out the tangential momentum. 
-    Sets stage by specifying a function f of time which may either be a
-    vector function or a scalar function
-
-    Example:
-
-    def waveform(t):
-        return sea_level + normalized_amplitude/cosh(t-25)**2
-
-    Bts = Transmissive_n_momentum_zero_t_momentum_set_stage_boundary(domain, waveform)
-
-    Underlying domain must be specified when boundary is instantiated
-    """
-
-    ##
-    # @brief Instantiate a Transmissive_n_momentum_zero_t_momentum_set_stage_boundary.
-    # @param domain
-    # @param function
-    def __init__(self, domain=None, function=None):
-        Boundary.__init__(self)
-
-        if domain is None:
-            msg = 'Domain must be specified for this type boundary'
-            raise Exception, msg
-
-        if function is None:
-            msg = 'Function must be specified for this type boundary'
-            raise Exception, msg
-
-        self.domain = domain
-        self.function = function
-
-    ##
-    # @brief Return a representation of this instance.
-    def __repr__(self):
-        return 'Transmissive_n_momentum_zero_t_momentum_set_stage_boundary(%s)' %self.domain
-
-    ##
-    # @brief Calculate transmissive results.
-    # @param vol_id 
-    # @param edge_id 
-    def evaluate(self, vol_id, edge_id):
-        """Transmissive_n_momentum_zero_t_momentum_set_stage_boundary
-        return the edge momentum values of the volume they serve.
-        """
-
-        q = self.domain.get_conserved_quantities(vol_id, edge = edge_id)
-
-        normal = self.domain.get_normal(vol_id, edge_id)
-
-
-        t = self.domain.get_time()
-
-        if hasattr(self.function, 'time'):
-            # Roll boundary over if time exceeds
-            while t > self.function.time[-1]:
-                msg = 'WARNING: domain time %.2f has exceeded' % t
-                msg += 'time provided in '
-                msg += 'transmissive_momentum_set_stage_boundary object.\n'
-                msg += 'I will continue, reusing the object from t==0'
-                log.critical(msg)
-                t -= self.function.time[-1]
-
-        value = self.function(t)
-        try:
-            x = float(value)
-        except:
-            x = float(value[0])
-
-        ## import math
-        ## if vol_id == 9433:
-        ##     print 'vol_id = ',vol_id, ' edge_id = ',edge_id, 'q = ', q, ' x = ',x
-        ##     print 'normal = ', normal
-        ##     print 'n . p = ', (normal[0]*q[1] + normal[1]*q[2])
-        ##     print 't . p = ', (normal[1]*q[1] - normal[0]*q[2])
-
-
-        q[0] = x
-        ndotq = (normal[0]*q[1] + normal[1]*q[2])
-        q[1] = normal[0]*ndotq
-        q[2] = normal[1]*ndotq
-
-            
-        return q
-
-##
-# @brief A transmissive boundary, momentum set to zero.
-# @note Inherits from Bouondary.
-class Transmissive_stage_zero_momentum_boundary(Boundary):
-    """Return same stage as those present in its neighbour volume.
-    Set momentum to zero.
-
-    Underlying domain must be specified when boundary is instantiated
-    """
-
-    ##
-    # @brief Instantiate a Transmissive (zero momentum) boundary.
-    # @param domain
-    def __init__(self, domain=None):
-        Boundary.__init__(self)
-
-        if domain is None:
-            msg = ('Domain must be specified for '
-                   'Transmissive_stage_zero_momentum boundary')
-            raise Exception, msg
-
-        self.domain = domain
-
-    ##
-    # @brief Return a representation of this instance.
-    def __repr__(self):
-        return 'Transmissive_stage_zero_momentum_boundary(%s)' % self.domain
-
-    ##
-    # @brief Calculate transmissive (zero momentum) results.
-    # @param vol_id 
-    # @param edge_id 
-    def evaluate(self, vol_id, edge_id):
-        """Transmissive boundaries return the edge values
-        of the volume they serve.
-        """
-
-        q = self.domain.get_conserved_quantities(vol_id, edge=edge_id)
-
-        q[1] = q[2] = 0.0
-        return q
-
-
-##
-# @brief Class for a Dirichlet discharge boundary.
-# @note Inherits from Boundary.
-class Dirichlet_discharge_boundary(Boundary):
-    """
-    Sets stage (stage0)
-    Sets momentum (wh0) in the inward normal direction.
-
-    Underlying domain must be specified when boundary is instantiated
-    """
-
-    ##
-    # @brief Instantiate a Dirichlet discharge boundary.
-    # @param domain
-    # @param stage0
-    # @param wh0
-    def __init__(self, domain=None, stage0=None, wh0=None):
-        Boundary.__init__(self)
-
-        if domain is None:
-            msg = 'Domain must be specified for this type of boundary'
-            raise Exception, msg
-
-        if stage0 is None:
-            raise Exception, 'Stage must be specified for this type of boundary'
-
-        if wh0 is None:
-            wh0 = 0.0
-
-        self.domain = domain
-        self.stage0 = stage0
-        self.wh0 = wh0
-
-    ##
-    # @brief Return a representation of this instance.
-    def __repr__(self):
-        return 'Dirichlet_Discharge_boundary(%s)' % self.domain
-
-    ##
-    # @brief Calculate Dirichlet discharge boundary results.
-    # @param vol_id 
-    # @param edge_id 
-    def evaluate(self, vol_id, edge_id):
-        """Set discharge in the (inward) normal direction"""
-
-        normal = self.domain.get_normal(vol_id,edge_id)
-        q = [self.stage0, -self.wh0*normal[0], -self.wh0*normal[1]]
-        return q
-
-        # FIXME: Consider this (taken from File_boundary) to allow
-        # spatial variation
-        # if vol_id is not None and edge_id is not None:
-        #     i = self.boundary_indices[ vol_id, edge_id ]
-        #     return self.F(t, point_id = i)
-        # else:
-        #     return self.F(t)
-
-
-# Backward compatibility
-# FIXME(Ole): Deprecate
-##
-# @brief Deprecated
-class Dirichlet_Discharge_boundary(Dirichlet_discharge_boundary):
-    pass
-
-
-class Inflow_boundary(Boundary):
-    """Apply given flow in m^3/s to boundary segment.
-    Depth and momentum is derived using Manning's formula.
-
-    Underlying domain must be specified when boundary is instantiated
-    """
-    
-    # FIXME (Ole): This is work in progress and definitely not finished.
-    # The associated test has been disabled
-
-    def __init__(self, domain=None, rate=0.0):
-        Boundary.__init__(self)
-
-        if domain is None:
-            msg = 'Domain must be specified for '
-            msg += 'Inflow boundary'
-            raise Exception, msg
-
-        self.domain = domain
-        
-        # FIXME(Ole): Allow rate to be time dependent as well
-        self.rate = rate
-        self.tag = None # Placeholder for tag associated with this object.
-
-    def __repr__(self):
-        return 'Inflow_boundary(%s)' %self.domain
-
-    def evaluate(self, vol_id, edge_id):
-        """Apply inflow rate at each edge of this boundary
-        """
-        
-        # First find all segments having the same tag is vol_id, edge_id
-        # This will be done the first time evaluate is called.
-        if self.tag is None:
-            boundary = self.domain.boundary
-            self.tag = boundary[(vol_id, edge_id)]        
-            
-            # Find total length of boundary with this tag
-            length = 0.0
-            for v_id, e_id in boundary:
-                if self.tag == boundary[(v_id, e_id)]:
-                    length += self.domain.mesh.get_edgelength(v_id, e_id)            
-
-            self.length = length
-            self.average_momentum = self.rate/length
-            
-            
-        # Average momentum has now been established across this boundary
-        # Compute momentum in the inward normal direction 
-        
-        inward_normal = -self.domain.mesh.get_normal(vol_id, edge_id)       
-        xmomentum, ymomentum = self.average_momentum * inward_normal
-            
-        # Compute depth based on Manning's formula v = 1/n h^{2/3} sqrt(S)
-        # Where v is velocity, n is manning's coefficient, h is depth and S is the slope into the domain. 
-        # Let mu be the momentum (vh), then this equation becomes: mu = 1/n h^{5/3} sqrt(S) 
-        # from which we can isolate depth to get
-        # h = (mu n/sqrt(S) )^{3/5} 
-        
-        slope = 0 # get gradient for this triangle dot normal
-        
-        # get manning coef from this triangle
-        friction = self.domain.get_quantity('friction').get_values(location='edges', 
-                                                                   indices=[vol_id])[0]
-        mannings_n = friction[edge_id]
-
-        if slope > epsilon and mannings_n > epsilon:
-            depth = pow(self.average_momentum * mannings_n/math.sqrt(slope), 3.0/5) 
-        else:
-            depth = 1.0
-            
-        # Elevation on this edge    
-        
-        z = self.domain.get_quantity('elevation').get_values(location='edges', 
-                                                             indices=[vol_id])[0]
-        elevation = z[edge_id]
-            
-        # Assign conserved quantities and return
-        q = num.array([elevation + depth, xmomentum, ymomentum], num.Float)
-        return q
-
-
-        
-    
-            
-        
-class Field_boundary(Boundary):
-    """Set boundary from given field represented in an sww file containing
-    values for stage, xmomentum and ymomentum.
-
-    Optionally, the user can specify mean_stage to offset the stage provided
-    in the sww file.
-
-    This function is a thin wrapper around the generic File_boundary. The
-    difference between the file_boundary and field_boundary is only that the
-    field_boundary will allow you to change the level of the stage height when
-    you read in the boundary condition. This is very useful when running
-    different tide heights in the same area as you need only to convert one
-    boundary condition to a SWW file, ideally for tide height of 0 m
-    (saving disk space). Then you can use field_boundary to read this SWW file
-    and change the stage height (tide) on the fly depending on the scenario.
-    """
-
-    ##
-    # @brief Construct an instance of a 'field' boundary.
-    # @param filename Name of SWW file containing stage, x and ymomentum.
-    # @param domain Shallow water domain for which the boundary applies.
-    # @param mean_stage Mean water level added to stage derived from SWW file.
-    # @param time_thinning Time step thinning factor.
-    # @param time_limit 
-    # @param boundary_polygon 
-    # @param default_boundary None or an instance of Boundary.
-    # @param use_cache True if caching is to be used.
-    # @param verbose True if this method is to be verbose.
-    def __init__(self,
-                 filename,
-                 domain,
-                 mean_stage=0.0,
-                 time_thinning=1,
-                 time_limit=None,
-                 boundary_polygon=None,
-                 default_boundary=None,
-                 use_cache=False,
-                 verbose=False):
-        """Constructor
-
-        filename: Name of sww file
-        domain: pointer to shallow water domain for which the boundary applies
-        mean_stage: The mean water level which will be added to stage derived
-                    from the boundary condition
-        time_thinning: Will set how many time steps from the sww file read in
-                       will be interpolated to the boundary. For example if
-                       the sww file has 1 second time steps and is 24 hours
-                       in length it has 86400 time steps. If you set
-                       time_thinning to 1 it will read all these steps.
-                       If you set it to 100 it will read every 100th step eg
-                       only 864 step. This parameter is very useful to increase
-                       the speed of a model run that you are setting up
-                       and testing.
-
-        default_boundary: Must be either None or an instance of a
-                          class descending from class Boundary.
-                          This will be used in case model time exceeds
-                          that available in the underlying data.
-
-                          Note that mean_stage will also be added to this.
-                                                
-        use_cache:
-        verbose:
-        """
-
-        # Create generic file_boundary object
-        self.file_boundary = File_boundary(filename,
-                                           domain,
-                                           time_thinning=time_thinning,
-                                           time_limit=time_limit,
-                                           boundary_polygon=boundary_polygon,
-                                           default_boundary=default_boundary,
-                                           use_cache=use_cache,
-                                           verbose=verbose)
-
-        # Record information from File_boundary
-        self.F = self.file_boundary.F
-        self.domain = self.file_boundary.domain
-
-        # Record mean stage
-        self.mean_stage = mean_stage
-
-    ##
-    # @note Generate a string representation of this instance.
-    def __repr__(self):
-        return 'Field boundary'
-
-    ##
-    # @brief Calculate 'field' boundary results.
-    # @param vol_id 
-    # @param edge_id 
-    def evaluate(self, vol_id=None, edge_id=None):
-        """Return linearly interpolated values based on domain.time
-
-        vol_id and edge_id are ignored
-        """
-
-        # Evaluate file boundary
-        q = self.file_boundary.evaluate(vol_id, edge_id)
-
-        # Adjust stage
-        for j, name in enumerate(self.domain.conserved_quantities):
-            if name == 'stage':
-                q[j] += self.mean_stage
-        return q
-
 
 ################################################################################
@@ -2826,5 +2283,5 @@
 if compile.can_use_C_extension('shallow_water_ext.c'):
     # Underlying C implementations can be accessed
-    from shallow_water_ext import rotate, assign_windfield_values
+    from shallow_water_ext import assign_windfield_values
 else:
     msg = 'C implementations could not be accessed by %s.\n ' % __file__
Index: /anuga_core/source/anuga/shallow_water/test_read_sww.py
===================================================================
--- /anuga_core/source/anuga/shallow_water/test_read_sww.py	(revision 7730)
+++ /anuga_core/source/anuga/shallow_water/test_read_sww.py	(revision 7731)
@@ -37,6 +37,7 @@
         from anuga.interface import rectangular_cross
         from anuga.interface import Domain
-        from anuga.interface import Reflective_boundary
-        from anuga.interface import Dirichlet_boundary
+        from boundaries import Reflective_boundary
+        from anuga.abstract_2d_finite_volumes.generic_boundary_conditions\
+                            import Dirichlet_boundary  
         from anuga.interface import Time_boundary
 
Index: /anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py
===================================================================
--- /anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py	(revision 7730)
+++ /anuga_core/source/anuga/shallow_water/test_shallow_water_domain.py	(revision 7731)
@@ -8,13 +8,27 @@
 from anuga.config import g, epsilon
 from anuga.config import netcdf_mode_r, netcdf_mode_w, netcdf_mode_a
-from anuga.utilities.numerical_tools import mean
+from anuga.utilities.numerical_tools import mean, ensure_numeric
 from anuga.geometry.polygon import is_inside_polygon
 from anuga.coordinate_transforms.geo_reference import Geo_reference
-from anuga.abstract_2d_finite_volumes.quantity import Quantity
 from anuga.geospatial_data.geospatial_data import Geospatial_data
 from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
+from anuga.abstract_2d_finite_volumes.quantity import Quantity
 
 from anuga.utilities.system_tools import get_pathname_from_package
-from shallow_water_domain import *
+
+from anuga.shallow_water import Domain
+from anuga.abstract_2d_finite_volumes.generic_boundary_conditions \
+        import Dirichlet_boundary
+from anuga.shallow_water.shallow_water_domain import Rainfall, Wind_stress
+from anuga.shallow_water.shallow_water_domain import Inflow, Cross_section
+from anuga.shallow_water.data_manager import get_flow_through_cross_section
+
+# boundary functions
+from anuga.shallow_water.boundaries import Reflective_boundary, \
+            Field_boundary, Transmissive_momentum_set_stage_boundary, \
+            Transmissive_stage_zero_momentum_boundary
+from anuga.abstract_2d_finite_volumes.generic_boundary_conditions\
+     import Transmissive_boundary, Dirichlet_boundary, \
+            Time_boundary, File_boundary, AWI_boundary
 
 import numpy as num
@@ -22,4 +36,5 @@
 # Get gateway to C implementation of flux function for direct testing
 from shallow_water_ext import flux_function_central as flux_function
+from shallow_water_ext import rotate
 
 
@@ -6601,6 +6616,4 @@
                 import rectangular_cross
         from anuga.shallow_water import Domain
-        from anuga.shallow_water.shallow_water_domain import Reflective_boundary
-        from anuga.shallow_water.shallow_water_domain import Dirichlet_boundary
         from anuga.shallow_water.shallow_water_domain import Inflow
         from anuga.shallow_water.data_manager \
@@ -6694,6 +6707,4 @@
         from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
         from anuga.shallow_water import Domain
-        from anuga.shallow_water.shallow_water_domain import Reflective_boundary
-        from anuga.shallow_water.shallow_water_domain import Dirichlet_boundary
         from anuga.shallow_water.shallow_water_domain import Inflow
         from anuga.shallow_water.data_manager import get_flow_through_cross_section
@@ -6790,14 +6801,4 @@
         verbose = False
         
-
-        #---------------------------------------------------------------------
-        # Import necessary modules
-        #---------------------------------------------------------------------
-        from anuga.abstract_2d_finite_volumes.mesh_factory import rectangular_cross
-        from anuga.shallow_water import Domain
-        from anuga.shallow_water.shallow_water_domain import Reflective_boundary
-        from anuga.shallow_water.shallow_water_domain import Dirichlet_boundary
-        from anuga.shallow_water.shallow_water_domain import Rainfall
-        from anuga.shallow_water.data_manager import get_flow_through_cross_section
 
         #----------------------------------------------------------------------
@@ -7125,20 +7126,4 @@
         verbose = False
         
-
-        #----------------------------------------------------------------------
-        # Import necessary modules
-        #----------------------------------------------------------------------
-
-        from anuga.abstract_2d_finite_volumes.mesh_factory \
-                import rectangular_cross
-        from anuga.shallow_water import Domain
-        from anuga.shallow_water.shallow_water_domain import Reflective_boundary
-        from anuga.shallow_water.shallow_water_domain import Dirichlet_boundary
-        from anuga.shallow_water.shallow_water_domain import Inflow
-        from anuga.shallow_water.data_manager \
-                import get_flow_through_cross_section
-        from anuga.abstract_2d_finite_volumes.util \
-                import sww2csv_gauges, csv2timeseries_graphs
-
         #----------------------------------------------------------------------
         # Setup computational domain
