def __init__(self, time, quantities, quantity_names=None, vertex_coordinates=None, triangles=None, interpolation_points=None, time_thinning=1, verbose=False, gauge_neighbour_id=None, output_centroids=False): """Initialise object and build spatial interpolation if required Time_thinning_number controls how many timesteps to use. Only timesteps with index%time_thinning_number == 0 will used, or in other words a value of 3, say, will cause the algorithm to use every third time step. """ from anuga.config import time_format if verbose is True: log.critical('Interpolation_function: input checks') # Check temporal info time = ensure_numeric(time) if not num.alltrue(time[1:] - time[:-1] >= 0): # This message is time consuming to form due to the conversion of msg = 'Time must be a monotonuosly increasing sequence %s' % time raise Exception(msg) # Check if quantities is a single array only if not isinstance(quantities, dict): quantities = ensure_numeric(quantities) quantity_names = ['Attribute'] # Make it a dictionary quantities = {quantity_names[0]: quantities} # Use keys if no names are specified if quantity_names is None: quantity_names = quantities.keys() # Check spatial info if vertex_coordinates is None: self.spatial = False else: # FIXME (Ole): Try ensure_numeric here - # this function knows nothing about georefering. vertex_coordinates = ensure_absolute(vertex_coordinates) if triangles is not None: triangles = ensure_numeric(triangles) self.spatial = True if verbose is True: log.critical('Interpolation_function: thinning by %d' % time_thinning) # Thin timesteps if needed # Note array() is used to make the thinned arrays contiguous in memory self.time = num.array(time[::time_thinning]) for name in quantity_names: if len(quantities[name].shape) == 2: quantities[name] = num.array(quantities[name][::time_thinning,:]) if verbose is True: log.critical('Interpolation_function: precomputing') # Save for use with statistics self.quantities_range = {} for name in quantity_names: q = quantities[name][:].flatten() self.quantities_range[name] = [min(q), max(q)] self.quantity_names = quantity_names self.vertex_coordinates = vertex_coordinates self.interpolation_points = interpolation_points self.index = 0 # Initial time index self.precomputed_values = {} self.centroids = [] # Precomputed spatial interpolation if requested if interpolation_points is not None: #no longer true. sts files have spatial = True but #if self.spatial is False: # raise Exception('Triangles and vertex_coordinates must be specified') # try: self.interpolation_points = \ interpolation_points = ensure_numeric(interpolation_points) except: msg = 'Interpolation points must be an N x 2 numeric array ' \ 'or a list of points\n' msg += 'Got: %s.' %(str(self.interpolation_points)[:60] + '...') raise Exception(msg) # Ensure 'mesh_boundary_polygon' is defined mesh_boundary_polygon = None if triangles is not None and vertex_coordinates is not None: # Check that all interpolation points fall within # mesh boundary as defined by triangles and vertex_coordinates. from anuga.abstract_2d_finite_volumes.neighbour_mesh import Mesh from anuga.geometry.polygon import outside_polygon # Create temporary mesh object from mesh info passed # into this function. mesh = Mesh(vertex_coordinates, triangles) mesh_boundary_polygon = mesh.get_boundary_polygon() indices = outside_polygon(interpolation_points, mesh_boundary_polygon) # Record result #self.mesh_boundary_polygon = mesh_boundary_polygon self.indices_outside_mesh = indices # Report if len(indices) > 0: msg = 'Interpolation points in Interpolation function fall ' msg += 'outside specified mesh. Offending points:\n' out_interp_pts = [] for i in indices: msg += '%d: %s\n' % (i, interpolation_points[i]) out_interp_pts.append( ensure_numeric(interpolation_points[i])) if verbose is True: import sys from anuga.geometry.polygon import plot_polygons title = ('Interpolation points fall ' 'outside specified mesh') plot_polygons([mesh_boundary_polygon, interpolation_points, out_interp_pts], ['line', 'point', 'outside'], figname='points_boundary_out', label=title) # Joaquim Luis suggested this as an Exception, so # that the user can now what the problem is rather than # looking for NaN's. However, NANs are handy as they can # be ignored leaving good points for continued processing. if verbose: log.critical(msg) #raise Exception(msg) elif triangles is None and vertex_coordinates is not None: #jj #Dealing with sts file pass else: raise Exception('Sww file function requires both triangles and ' 'vertex_coordinates. sts file file function ' 'requires the latter.') # Plot boundary and interpolation points, # but only if if 'mesh_boundary_polygon' has data. if verbose is True and mesh_boundary_polygon is not None: import sys if sys.platform == 'win32': from anuga.geometry.polygon import plot_polygons title = ('Interpolation function: ' 'Polygon and interpolation points') plot_polygons([mesh_boundary_polygon, interpolation_points], ['line', 'point'], figname='points_boundary', label=title) m = len(self.interpolation_points) p = len(self.time) for name in quantity_names: self.precomputed_values[name] = num.zeros((p, m), num.float) if verbose is True: log.critical('Build interpolator') # Build interpolator if triangles is not None and vertex_coordinates is not None: if verbose: msg = 'Building interpolation matrix from source mesh ' msg += '(%d vertices, %d triangles)' \ % (vertex_coordinates.shape[0], triangles.shape[0]) log.critical(msg) # This one is no longer needed for STS files interpol = Interpolate(vertex_coordinates, triangles, verbose=verbose) elif triangles is None and vertex_coordinates is not None: if verbose: log.critical('Interpolation from STS file') if verbose: log.critical('Interpolating (%d interpolation points, %d timesteps).' % (self.interpolation_points.shape[0], self.time.shape[0])) if time_thinning > 1: log.critical('Timesteps were thinned by a factor of %d' % time_thinning) else: log.critical() for i, t in enumerate(self.time): # Interpolate quantities at this timestep #if verbose and i%((p+10)/10) == 0: if verbose: log.critical(' time step %d of %d' % (i, p)) for name in quantity_names: if len(quantities[name].shape) == 2: Q = quantities[name][i,:] # Quantities at timestep i else: Q = quantities[name][:] # No time dependency #if verbose and i%((p+10)/10) == 0: if verbose: log.critical(' quantity %s, size=%d' % (name, len(Q))) # Interpolate if triangles is not None and vertex_coordinates is not None: result = interpol.interpolate(Q, point_coordinates=\ self.interpolation_points, verbose=False, output_centroids=output_centroids) self.centroids = interpol.centroids elif triangles is None and vertex_coordinates is not None: result = interpolate_polyline(Q, vertex_coordinates, gauge_neighbour_id, interpolation_points=\ self.interpolation_points) #assert len(result), len(interpolation_points) self.precomputed_values[name][i, :] = result # Report if verbose: log.critical(self.statistics()) else: # Store quantitites as is for name in quantity_names: self.precomputed_values[name] = quantities[name]
def __init__(self, time, quantities, quantity_names=None, vertex_coordinates=None, triangles=None, interpolation_points=None, time_thinning=1, verbose=False, gauge_neighbour_id=None, output_centroids=False): """Initialise object and build spatial interpolation if required Time_thinning_number controls how many timesteps to use. Only timesteps with index%time_thinning_number == 0 will used, or in other words a value of 3, say, will cause the algorithm to use every third time step. """ from anuga.config import time_format if verbose is True: log.critical('Interpolation_function: input checks') # Check temporal info time = ensure_numeric(time) if not num.alltrue(time[1:] - time[:-1] >= 0): # This message is time consuming to form due to the conversion of msg = 'Time must be a monotonuosly increasing sequence %s' % time raise Exception(msg) # Check if quantities is a single array only if not isinstance(quantities, dict): quantities = ensure_numeric(quantities) quantity_names = ['Attribute'] # Make it a dictionary quantities = {quantity_names[0]: quantities} # Use keys if no names are specified if quantity_names is None: quantity_names = list(quantities.keys()) # Check spatial info if vertex_coordinates is None: self.spatial = False else: # FIXME (Ole): Try ensure_numeric here - # this function knows nothing about georefering. vertex_coordinates = ensure_absolute(vertex_coordinates) if triangles is not None: triangles = ensure_numeric(triangles) self.spatial = True if verbose is True: log.critical('Interpolation_function: thinning by %d' % time_thinning) # Thin timesteps if needed # Note array() is used to make the thinned arrays contiguous in memory self.time = num.array(time[::time_thinning]) for name in quantity_names: if len(quantities[name].shape) == 2: quantities[name] = num.array( quantities[name][::time_thinning, :]) if verbose is True: log.critical('Interpolation_function: precomputing') # Save for use with statistics self.quantities_range = {} for name in quantity_names: q = quantities[name][:].flatten() self.quantities_range[name] = [min(q), max(q)] self.quantity_names = quantity_names self.vertex_coordinates = vertex_coordinates self.interpolation_points = interpolation_points self.index = 0 # Initial time index self.precomputed_values = {} self.centroids = [] # Precomputed spatial interpolation if requested if interpolation_points is not None: #no longer true. sts files have spatial = True but #if self.spatial is False: # raise Exception('Triangles and vertex_coordinates must be specified') # try: self.interpolation_points = \ interpolation_points = ensure_numeric(interpolation_points) except: msg = 'Interpolation points must be an N x 2 numeric array ' \ 'or a list of points\n' msg += 'Got: %s.' % (str(self.interpolation_points)[:60] + '...') raise Exception(msg) # Ensure 'mesh_boundary_polygon' is defined mesh_boundary_polygon = None if triangles is not None and vertex_coordinates is not None: # Check that all interpolation points fall within # mesh boundary as defined by triangles and vertex_coordinates. from anuga.abstract_2d_finite_volumes.neighbour_mesh import Mesh from anuga.geometry.polygon import outside_polygon # Create temporary mesh object from mesh info passed # into this function. mesh = Mesh(vertex_coordinates, triangles) mesh_boundary_polygon = mesh.get_boundary_polygon() indices = outside_polygon(interpolation_points, mesh_boundary_polygon) # Record result #self.mesh_boundary_polygon = mesh_boundary_polygon self.indices_outside_mesh = indices # Report if len(indices) > 0: msg = 'Interpolation points in Interpolation function fall ' msg += 'outside specified mesh. Offending points:\n' out_interp_pts = [] for i in indices: msg += '%d: %s\n' % (i, interpolation_points[i]) out_interp_pts.append( ensure_numeric(interpolation_points[i])) if verbose is True: import sys from anuga.geometry.polygon import plot_polygons title = ('Interpolation points fall ' 'outside specified mesh') plot_polygons([ mesh_boundary_polygon, interpolation_points, out_interp_pts ], ['line', 'point', 'outside'], figname='points_boundary_out', label=title) # Joaquim Luis suggested this as an Exception, so # that the user can now what the problem is rather than # looking for NaN's. However, NANs are handy as they can # be ignored leaving good points for continued processing. if verbose: log.critical(msg) #raise Exception(msg) elif triangles is None and vertex_coordinates is not None: #jj #Dealing with sts file pass else: raise Exception( 'Sww file function requires both triangles and ' 'vertex_coordinates. sts file file function ' 'requires the latter.') # Plot boundary and interpolation points, # but only if if 'mesh_boundary_polygon' has data. if verbose is True and mesh_boundary_polygon is not None: import sys if sys.platform == 'win32': from anuga.geometry.polygon import plot_polygons title = ('Interpolation function: ' 'Polygon and interpolation points') plot_polygons( [mesh_boundary_polygon, interpolation_points], ['line', 'point'], figname='points_boundary', label=title) m = len(self.interpolation_points) p = len(self.time) for name in quantity_names: self.precomputed_values[name] = num.zeros((p, m), num.float) if verbose is True: log.critical('Build interpolator') # Build interpolator if triangles is not None and vertex_coordinates is not None: if verbose: msg = 'Building interpolation matrix from source mesh ' msg += '(%d vertices, %d triangles)' \ % (vertex_coordinates.shape[0], triangles.shape[0]) log.critical(msg) # This one is no longer needed for STS files interpol = Interpolate(vertex_coordinates, triangles, verbose=verbose) elif triangles is None and vertex_coordinates is not None: if verbose: log.critical('Interpolation from STS file') if verbose: log.critical( 'Interpolating (%d interpolation points, %d timesteps).' % (self.interpolation_points.shape[0], self.time.shape[0])) if time_thinning > 1: log.critical('Timesteps were thinned by a factor of %d' % time_thinning) else: log.critical() for i, t in enumerate(self.time): # Interpolate quantities at this timestep #if verbose and i%((p+10)/10) == 0: if verbose: log.critical(' time step %d of %d' % (i, p)) for name in quantity_names: if len(quantities[name].shape) == 2: Q = quantities[name][i, :] # Quantities at timestep i else: Q = quantities[name][:] # No time dependency #if verbose and i%((p+10)/10) == 0: if verbose: log.critical(' quantity %s, size=%d' % (name, len(Q))) # Interpolate if triangles is not None and vertex_coordinates is not None: result = interpol.interpolate(Q, point_coordinates=\ self.interpolation_points, verbose=False, output_centroids=output_centroids) self.centroids = interpol.centroids elif triangles is None and vertex_coordinates is not None: result = interpolate_polyline(Q, vertex_coordinates, gauge_neighbour_id, interpolation_points=\ self.interpolation_points) #assert len(result), len(interpolation_points) self.precomputed_values[name][i, :] = result # Report if verbose: log.critical(self.statistics()) else: # Store quantitites as is for name in quantity_names: self.precomputed_values[name] = quantities[name]
from anuga.geometry.polygon import plot_polygons from culvert_polygons import create_culvert_polygons # Culvert location x0 = 5.0; y0 = 5.0 # One end x1 = 15.0; y1 = 20.0 # Other end # Culvert Size culvert_width=2.4 culvert_height=1.2 # Call function P = create_culvert_polygons(end_point0=[x0, y0], end_point1=[x1, y1], width=culvert_width, height=culvert_height) culv_polygon = [[x0,y0], [x1,y1]] plot_polygons([culv_polygon, P['exchange_polygon0'], P['exchange_polygon1'], P['enquiry_polygon0'], P['enquiry_polygon1']], figname='culvert_polygon_example')