class ElementFinder(MeshBase): """ Used to determine which element a point lives in. Uses an order 1 HdivElement to get normals to each element, which is cute, but duplicates BoundaryQuadrature a bit""" def __init__(self): from elements import HdivElements MeshBase.__init__(self) self.hdivdegs = HdivElements(1) self.centres = [] self.degrees = [] def addPyramid(self, pointids): pds = [] points = self.getPoints(pointids) # print "addPyramid",points pds.extend([self.hdivdegs.triangle(points[t]) for t in [[0,1,4],[1,2,4],[2,3,4],[3,0,4]]]) pds.append(self.hdivdegs.quad(points[0:4])) self.degrees.append(DegreeSet(pds)) self.centres.append(numpy.sum(points, axis=0)/5.0) def elementPointMap(self, points): """ given a collection of points, return an element->point map""" etop = []#[[] for _ in range(len(self.degrees))] unassigned = numpy.ones(len(points), dtype=bool) for centre, degrees in zip(self.centres, self.degrees): fpoints = lambda p: points[newaxis,:,:] - p[:,newaxis,:] fcentre = lambda p: centre.reshape(1,1,3) - p[:,newaxis,:] cdofs = numpy.vstack(degrees.evaluatedofs(fcentre)) pdofs = numpy.vstack(degrees.evaluatedofs(fpoints)) ps = numpy.where(numpy.logical_and(numpy.sum(pdofs * numpy.sign(cdofs) >= 0,axis=0)==5, unassigned)) etop.append(ps[0]) unassigned[ps[0]] = False return etop
def __init__(self): from elements import HdivElements MeshBase.__init__(self) self.hdivdegs = HdivElements(1) self.centres = [] self.degrees = []