def get_face_index_shuffle_lookup_map_for_nodes(self, face_nodes): first_face_vertex_node_index_lists = \ self.geometry.face_vertices(self.vertex_indices())[0] def check_and_chop(pt): assert abs(pt[-1] - (-1)) < 1e-13 return pt[:-1] unodes = self.unit_nodes() face_unit_vertices = [ check_and_chop(unodes[i]) for i in first_face_vertex_node_index_lists ] class FaceIndexShuffle: def __init__(self, vert_perm, idx_map): self.vert_perm = vert_perm self.idx_map = idx_map def __hash__(self): return hash(self.vert_perm) def __eq__(self, other): return self.vert_perm == other.vert_perm def __call__(self, indices): return tuple(indices[i] for i in self.idx_map) result = {} from pytools import generate_unique_permutations for vert_perm in generate_unique_permutations( tuple(range(self.dimensions))): permuted_face_unit_vertices = [ face_unit_vertices[i] for i in vert_perm ] from hedge.tools.affine import identify_affine_map amap = identify_affine_map(face_unit_vertices, permuted_face_unit_vertices) from hedge.tools.indexing import find_index_map_from_node_sets imap = find_index_map_from_node_sets( face_nodes, [amap(node) for node in face_nodes]) result[vert_perm] = FaceIndexShuffle(vert_perm, imap) return result
def get_face_index_shuffle_lookup_map_for_nodes(self, face_nodes): first_face_vertex_node_index_lists = \ self.geometry.face_vertices(self.vertex_indices())[0] def check_and_chop(pt): assert abs(pt[-1] - (-1)) < 1e-13 return pt[:-1] unodes = self.unit_nodes() face_unit_vertices = [check_and_chop(unodes[i]) for i in first_face_vertex_node_index_lists] class FaceIndexShuffle: def __init__(self, vert_perm, idx_map): self.vert_perm = vert_perm self.idx_map = idx_map def __hash__(self): return hash(self.vert_perm) def __eq__(self, other): return self.vert_perm == other.vert_perm def __call__(self, indices): return tuple(indices[i] for i in self.idx_map) result = {} from pytools import generate_unique_permutations for vert_perm in generate_unique_permutations( tuple(range(self.dimensions))): permuted_face_unit_vertices = [ face_unit_vertices[i] for i in vert_perm] from hedge.tools.affine import identify_affine_map amap = identify_affine_map( face_unit_vertices, permuted_face_unit_vertices) from hedge.tools.indexing import find_index_map_from_node_sets imap = find_index_map_from_node_sets( face_nodes, [amap(node) for node in face_nodes]) result[vert_perm] = FaceIndexShuffle(vert_perm, imap) return result
def test_identify_affine_map(): n = 5 randn = numpy.random.randn for i in range(10): a = numpy.eye(n) + 0.3*randn(n,n) b = randn(n) from hedge.tools.affine import AffineMap, identify_affine_map amap = AffineMap(a, b) from_points = [randn(n) for i in range(n+1)] to_points = [amap(fp) for fp in from_points] amap2 = identify_affine_map(from_points, to_points) assert la.norm(a-amap2.matrix) < 1e-12 assert la.norm(b-amap2.vector) < 1e-12
def face_affine_maps(self): """Return an affine map for each face that maps the (n-1)-dimensional face unit coordinates to their volume coordintes. """ face_vertex_node_index_lists = \ self.geometry.face_vertices(self.vertex_indices()) from pytools import flatten, one vertex_node_indices = set(flatten(face_vertex_node_index_lists)) def find_missing_node(face_vertex_node_indices): return unit_nodes[one(vertex_node_indices - set(face_vertex_node_indices))] unit_nodes = self.unit_nodes() sets_of_to_points = [ [unit_nodes[fvni] for fvni in face_vertex_node_indices] + [find_missing_node(face_vertex_node_indices)] for face_vertex_node_indices in face_vertex_node_index_lists ] from_points = sets_of_to_points[0] # Construct an affine map that promotes face nodes into volume # by appending -1, this should end up on the first face dim = self.dimensions from hedge.tools.affine import AffineMap from hedge.tools.linalg import unit_vector to_face_1 = AffineMap( numpy.vstack([ numpy.eye(dim - 1, dtype=numpy.float64), numpy.zeros(dim - 1) ]), -unit_vector(dim, dim - 1, dtype=numpy.float64)) def finish_affine_map(amap): return amap.post_compose(to_face_1) from hedge.tools.affine import identify_affine_map return [ finish_affine_map(identify_affine_map(from_points, to_points)) for to_points in sets_of_to_points ]
def face_affine_maps(self): """Return an affine map for each face that maps the (n-1)-dimensional face unit coordinates to their volume coordintes. """ face_vertex_node_index_lists = \ self.geometry.face_vertices(self.vertex_indices()) from pytools import flatten, one vertex_node_indices = set(flatten(face_vertex_node_index_lists)) def find_missing_node(face_vertex_node_indices): return unit_nodes[one( vertex_node_indices - set(face_vertex_node_indices))] unit_nodes = self.unit_nodes() sets_of_to_points = [[unit_nodes[fvni] for fvni in face_vertex_node_indices] + [find_missing_node(face_vertex_node_indices)] for face_vertex_node_indices in face_vertex_node_index_lists] from_points = sets_of_to_points[0] # Construct an affine map that promotes face nodes into volume # by appending -1, this should end up on the first face dim = self.dimensions from hedge.tools.affine import AffineMap from hedge.tools.linalg import unit_vector to_face_1 = AffineMap( numpy.vstack([ numpy.eye(dim-1, dtype=numpy.float64), numpy.zeros(dim-1)]), -unit_vector(dim, dim-1, dtype=numpy.float64)) def finish_affine_map(amap): return amap.post_compose(to_face_1) from hedge.tools.affine import identify_affine_map return [ finish_affine_map( identify_affine_map(from_points, to_points)) for to_points in sets_of_to_points]