def create_mesh_from_regions(bounding_polygon, boundary_tags, maximum_triangle_area=None, filename=None, interior_regions=None, interior_holes=None, hole_tags=None, poly_geo_reference=None, mesh_geo_reference=None, minimum_triangle_angle=28.0, fail_if_polygons_outside=True, breaklines=None, use_cache=False, verbose=True, regionPtArea=None): """Create mesh from bounding polygons, and resolutions. bounding_polygon is a list of points in Eastings and Northings, relative to the poly_geo_reference. Boundary tags is a dictionary of symbolic tags. For every tag there is a list of indices referring to segments associated with that tag. If a segment is omitted an Exception will be raised. maximum_triangle_area is the maximal area per triangle for the bounding polygon, excluding the interior regions. Interior_regions is a list of tuples consisting of (polygon, resolution) for each region to be separately refined. Do not have polygon lines cross or be on-top of each other. Also do not have polygon close to each other. NOTE: If a interior_region is outside the bounding_polygon it should throw an error Interior_holes is a list of polygons for each hole. hole_tags is an optional list of boundary tags for the holes, see boundary_tags parameter. This function does not allow segments to share points - use underlying pmesh functionality for that poly_geo_reference is the geo_reference of the bounding polygon and the interior polygons. If none, assume absolute. Please pass one though, since absolute references have a zone. mesh_geo_reference is the geo_reference of the mesh to be created. If none is given one will be automatically generated. It was use the lower left hand corner of bounding_polygon (absolute) as the x and y values for the geo_ref. breaklines is a list of polygons. These lines will be preserved by the triangulation algorithm - useful for coastlines, walls, etc. The polygons are not closed. Returns the mesh instance if no filename is given Note, interior regions should be fully nested, as overlaps may cause unintended resolutions. fail_if_polygons_outside: If True (the default) Exception in thrown where interior polygons fall outside bounding polygon. If False, these will be ignored and execution continued. """ if verbose: log.resource_usage_timing(log.logging.INFO, "start_") if verbose: log.timingInfo("maximum_triangle_area, " + str(maximum_triangle_area)) if verbose: log.timingInfo("minimum_triangle_angle, " + str(minimum_triangle_angle)) if verbose: log.timingInfo("startMesh, '%s'" % log.CurrentDateTime()) # Build arguments and keyword arguments for use with caching or apply. args = (bounding_polygon, boundary_tags) kwargs = { 'maximum_triangle_area': maximum_triangle_area, 'filename': filename, 'interior_regions': interior_regions, 'interior_holes': interior_holes, 'hole_tags': hole_tags, 'poly_geo_reference': poly_geo_reference, 'mesh_geo_reference': mesh_geo_reference, 'minimum_triangle_angle': minimum_triangle_angle, 'fail_if_polygons_outside': fail_if_polygons_outside, 'breaklines': breaklines, 'verbose': verbose, 'regionPtArea': regionPtArea } # FIXME (Ole): Should be bypassed one day. See ticket:14 # Call underlying engine with or without caching if use_cache is True: try: from anuga.caching import cache except: msg = 'Caching was requested, but caching module'+\ 'could not be imported' raise Exception(msg) m = cache(_create_mesh_from_regions, args, kwargs, verbose=verbose, compression=False) else: m = apply(_create_mesh_from_regions, args, kwargs) return m
def __init__(self, coordinates, triangles, boundary=None, tagged_elements=None, geo_reference=None, use_inscribed_circle=False, verbose=False): """ Build Mesh Input x,y coordinates (sequence of 2-tuples or Mx2 numeric array of floats) triangles (sequence of 3-tuples or Nx3 numeric array of non-negative integers). """ General_mesh.__init__(self, coordinates, triangles, geo_reference=geo_reference, use_inscribed_circle=use_inscribed_circle, verbose=verbose) if verbose: log.critical('Mesh: Initialising') N = len(self) #Number_of_triangles # Allocate arrays for neighbour data self.neighbours = -1*num.ones((N, 3), num.int) self.neighbour_edges = -1*num.ones((N, 3), num.int) self.number_of_boundaries = num.zeros(N, num.int) self.surrogate_neighbours = num.zeros((N, 3), num.int) #Get x,y coordinates for all triangles and store V = self.vertex_coordinates # Relative coordinates # #Initialise each triangle # if verbose: log.critical('Mesh: Computing centroids and radii') # for i in range(N): # if verbose and i % ((N+10)/10) == 0: log.critical('(%d/%d)' % (i, N)) # # x0, y0 = V[3*i, :] # x1, y1 = V[3*i+1, :] # x2, y2 = V[3*i+2, :] # # #x0 = V[i, 0]; y0 = V[i, 1] # #x1 = V[i, 2]; y1 = V[i, 3] # #x2 = V[i, 4]; y2 = V[i, 5] # # #Compute centroid # centroid = num.array([(x0 + x1 + x2)/3, (y0 + y1 + y2)/3], num.float) # self.centroid_coordinates[i] = centroid # # # if self.use_inscribed_circle == False: # #OLD code. Computed radii may exceed that of an # #inscribed circle # # #Midpoints # m0 = num.array([(x1 + x2)/2, (y1 + y2)/2], num.float) # m1 = num.array([(x0 + x2)/2, (y0 + y2)/2], num.float) # m2 = num.array([(x1 + x0)/2, (y1 + y0)/2], num.float) # # #The radius is the distance from the centroid of # #a triangle to the midpoint of the side of the triangle # #closest to the centroid # d0 = num.sqrt(num.sum( (centroid-m0)**2 )) # d1 = num.sqrt(num.sum( (centroid-m1)**2 )) # d2 = num.sqrt(num.sum( (centroid-m2)**2 )) # # self.radii[i] = min(d0, d1, d2) # # else: # #NEW code added by Peter Row. True radius # #of inscribed circle is computed # # a = num.sqrt((x0-x1)**2+(y0-y1)**2) # b = num.sqrt((x1-x2)**2+(y1-y2)**2) # c = num.sqrt((x2-x0)**2+(y2-y0)**2) # # self.radii[i]=2.0*self.areas[i]/(a+b+c) # # # #Initialise Neighbours (-1 means that it is a boundary neighbour) # self.neighbours[i, :] = [-1, -1, -1] # # #Initialise edge ids of neighbours # #In case of boundaries this slot is not used # self.neighbour_edges[i, :] = [-1, -1, -1] #Build neighbour structure if verbose: log.critical('Mesh: Building neigbour structure') self.build_neighbour_structure() #Build surrogate neighbour structure if verbose: log.critical('Mesh: Building surrogate neigbour structure') self.build_surrogate_neighbour_structure() #Build boundary dictionary mapping (id, edge) to symbolic tags if verbose: log.critical('Mesh: Building boundary dictionary') self.build_boundary_dictionary(boundary) #Update boundary_enumeration self.build_boundary_neighbours() #Build tagged element dictionary mapping (tag) to array of elements if verbose: log.critical('Mesh: Building tagged elements dictionary') self.build_tagged_elements_dictionary(tagged_elements) # Build a list of vertices that are not connected to any triangles self.lone_vertices = [] #Check that all vertices have been registered for node, count in enumerate(self.number_of_triangles_per_node): #msg = 'Node %d does not belong to an element.' %node #assert count > 0, msg if count == 0: self.lone_vertices.append(node) #Update boundary indices FIXME: OBSOLETE #self.build_boundary_structure() #FIXME check integrity? if verbose: log.critical('Mesh: Done') if verbose: log.timingInfo("finishMesh, '%s'" % log.CurrentDateTime()) if verbose: log.resource_usage_timing(log.logging.INFO, "finishMesh_")