def __init__(self, datamodel, points): """precomputations which are identical for all mappings""" self.datamodel = datamodel self.hierarchy = self.datamodel.hierarchy self.complex = self.hierarchy[-1] self.group = self.complex.group #cache the index a point is in. if it remains unchanged, no need to update count = len(points) self.index = np.zeros((3, count), np.int8) #precompute subtriangles primal = self.complex.geometry.primal[ self.complex.topology.FV] mid = util.normalize(np.roll(primal, +1, 1) + np.roll(primal, -1, 1)) dual = self.complex.geometry.dual basis = np.empty((self.complex.topology.D0, 3, 2, 3, 3)) for i in range(3): basis[:,i,0,0,:] = primal[:,i ,:] basis[:,i,1,0,:] = primal[:,i ,:] basis[:,i,0,1,:] = mid [:,i-2,:] basis[:,i,1,1,:] = mid [:,i-1,:] basis[:,:,:,2,:] = dual [:,None, None,:] #each subtri shares the dual vert self.subdomain = util.adjoint(basis) #precompute all we can for subdomain compu self.subdomain[:,:,1,:,:] *= -1 #flip sign self.subdomain = self.subdomain.reshape(-1,6,3,3) #fold sign axis self.update(points)
def triangle_invert(self): """ pre-invert triangle support. this is useful for computing projections on triangles adjoint is fine; we normalize coords anyway """ tri_coords = util.gather(self.topology.FV, self.primal) self.inverted_triangle = util.adjoint(tri_coords)
def subdivide_position(self, position): """calc primal coords from parent""" #one child for each parent vertex_vertex = position #each new vert lies at midpoint edge_vertex = util.normalize(self.edge_mid*vertex_vertex) #ordering convention is vertex-vertex + edge-vertex position = np.vstack((vertex_vertex, edge_vertex)) #calc subdivision planes central = util.gather(self.FEi, edge_vertex) planes = util.adjoint(central) return position, planes