def test_tri_face_node_distribution(): """Test whether the nodes on the faces of the triangle are distributed according to the same proportions on each face. If this is not the case, then reusing the same face mass matrix for each face would be invalid. """ from hedge.discretization.local import TriangleDiscretization tri = TriangleDiscretization(8) unodes = tri.unit_nodes() projected_face_points = [] for face_i in tri.face_indices(): start = unodes[face_i[0]] end = unodes[face_i[-1]] dir = end-start dir /= numpy.dot(dir, dir) pfp = numpy.array([numpy.dot(dir, unodes[i]-start) for i in face_i]) projected_face_points.append(pfp) first_points = projected_face_points[0] for points in projected_face_points[1:]: error = la.norm(points-first_points, numpy.Inf) assert error < 1e-15
def test_tri_face_node_distribution(): """Test whether the nodes on the faces of the triangle are distributed according to the same proportions on each face. If this is not the case, then reusing the same face mass matrix for each face would be invalid. """ from hedge.discretization.local import TriangleDiscretization tri = TriangleDiscretization(8) unodes = tri.unit_nodes() projected_face_points = [] for face_i in tri.face_indices(): start = unodes[face_i[0]] end = unodes[face_i[-1]] dir = end-start dir /= numpy.dot(dir, dir) pfp = numpy.array([numpy.dot(dir, unodes[i]-start) for i in face_i]) projected_face_points.append(pfp) first_points = projected_face_points[0] for points in projected_face_points[1:]: error = la.norm(points-first_points, numpy.Inf) assert error < 1e-15
def test_tri_map(): """Verify that the mapping and node-building operations maintain triangle vertices""" from hedge.discretization.local import TriangleDiscretization n = 8 tri = TriangleDiscretization(n) node_dict = dict((ituple, idx) for idx, ituple in enumerate(tri.node_tuples())) corner_indices = [node_dict[0,0], node_dict[n,0], node_dict[0,n]] unodes = tri.unit_nodes() corners = [unodes[i] for i in corner_indices] for i in range(10): vertices = [numpy.random.randn(2) for vi in range(3)] map = tri.geometry.get_map_unit_to_global(vertices) global_corners = [map(pt) for pt in corners] for gc, v in zip(global_corners, vertices): assert la.norm(gc-v) < 1e-12
def test_tri_map(): """Verify that the mapping and node-building operations maintain triangle vertices""" from hedge.discretization.local import TriangleDiscretization n = 8 tri = TriangleDiscretization(n) node_dict = dict((ituple, idx) for idx, ituple in enumerate(tri.node_tuples())) corner_indices = [node_dict[0,0], node_dict[n,0], node_dict[0,n]] unodes = tri.unit_nodes() corners = [unodes[i] for i in corner_indices] for i in range(10): vertices = [numpy.random.randn(2) for vi in range(3)] map = tri.geometry.get_map_unit_to_global(vertices) global_corners = [map(pt) for pt in corners] for gc, v in zip(global_corners, vertices): assert la.norm(gc-v) < 1e-12
def test_mapping_differences_tri(): """Check that triangle interpolation is independent of mapping to reference """ from hedge.discretization.local import TriangleDiscretization from random import random from pytools import generate_permutations def shift(list): return list[1:] + [list[0]] class LinearCombinationOfFunctions: def __init__(self, coefficients, functions, premap): self.coefficients = coefficients self.functions = functions self.premap = premap def __call__(self, x): return sum(coeff * f(self.premap(x)) for coeff, f in zip(self.coefficients, self.functions)) def random_barycentric_coordinates(dim): remain = 1 coords = [] for i in range(dim): coords.append(random() * remain) remain -= coords[-1] coords.append(remain) return coords tri = TriangleDiscretization(5) for trial_number in range(10): vertices = [numpy.random.randn(2) for vi in range(3)] map = tri.geometry.get_map_unit_to_global(vertices) nodes = [map(node) for node in tri.unit_nodes()] node_values = numpy.array([random() for node in nodes]) functions = [] for pvertices in generate_permutations(vertices): pmap = tri.geometry.get_map_unit_to_global(pvertices) pnodes = [pmap(node) for node in tri.unit_nodes()] # map from pnode# to node# nodematch = {} for pi, pn in enumerate(pnodes): for i, n in enumerate(nodes): if la.norm(n - pn) < 1e-13: nodematch[pi] = i break pnode_values = numpy.array( [node_values[nodematch[pi]] for pi in range(len(nodes))]) interp_f = LinearCombinationOfFunctions( la.solve(tri.vandermonde(), pnode_values), tri.basis_functions(), pmap.inverted()) # verify interpolation property #for n, nv in zip(pnodes, pnode_values): #assert abs(interp_f(n) - nv) < 1e-13 functions.append(interp_f) for subtrial_number in range(15): pt_in_element = sum(coeff * vertex for coeff, vertex in zip( random_barycentric_coordinates(2), vertices)) f_values = [f(pt_in_element) for f in functions] avg = sum(f_values) / len(f_values) err = [abs(fv - avg) for fv in f_values] assert max(err) < 1e-12
def test_mapping_differences_tri(): """Check that triangle interpolation is independent of mapping to reference """ from hedge.discretization.local import TriangleDiscretization from random import random from pytools import generate_permutations def shift(list): return list[1:] + [list[0]] class LinearCombinationOfFunctions: def __init__(self, coefficients, functions, premap): self.coefficients = coefficients self.functions = functions self.premap = premap def __call__(self, x): return sum(coeff * f(self.premap(x)) for coeff, f in zip(self.coefficients, self.functions)) def random_barycentric_coordinates(dim): remain = 1 coords = [] for i in range(dim): coords.append(random() * remain) remain -= coords[-1] coords.append(remain) return coords tri = TriangleDiscretization(5) for trial_number in range(10): vertices = [numpy.random.randn(2) for vi in range(3)] map = tri.geometry.get_map_unit_to_global(vertices) nodes = [map(node) for node in tri.unit_nodes()] node_values = numpy.array([random() for node in nodes]) functions = [] for pvertices in generate_permutations(vertices): pmap = tri.geometry.get_map_unit_to_global(pvertices) pnodes = [pmap(node) for node in tri.unit_nodes()] # map from pnode# to node# nodematch = {} for pi, pn in enumerate(pnodes): for i, n in enumerate(nodes): if la.norm(n - pn) < 1e-13: nodematch[pi] = i break pnode_values = numpy.array([node_values[nodematch[pi]] for pi in range(len(nodes))]) interp_f = LinearCombinationOfFunctions( la.solve(tri.vandermonde(), pnode_values), tri.basis_functions(), pmap.inverted() ) # verify interpolation property # for n, nv in zip(pnodes, pnode_values): # assert abs(interp_f(n) - nv) < 1e-13 functions.append(interp_f) for subtrial_number in range(15): pt_in_element = sum(coeff * vertex for coeff, vertex in zip(random_barycentric_coordinates(2), vertices)) f_values = [f(pt_in_element) for f in functions] avg = sum(f_values) / len(f_values) err = [abs(fv - avg) for fv in f_values] assert max(err) < 5e-13