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_")
def __repr__(self): return General_mesh.__repr__(self) + ', %d boundary segments'\ %(len(self.boundary))