From ee5171e12f7bc862637c9fcd61330560160fd23a Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Wed, 9 Jul 2014 00:24:45 -0500 Subject: [PATCH] Make generate_torus work --- examples/plot-connectivity.py | 8 +- meshmode/discretization/connection.py | 8 ++ meshmode/mesh/generation.py | 190 +++++++++++++------------- 3 files changed, 109 insertions(+), 97 deletions(-) diff --git a/examples/plot-connectivity.py b/examples/plot-connectivity.py index a888636..59db358 100644 --- a/examples/plot-connectivity.py +++ b/examples/plot-connectivity.py @@ -4,7 +4,7 @@ import numpy as np # noqa import pyopencl as cl -order = 3 +order = 4 def main(): @@ -12,9 +12,11 @@ def main(): queue = cl.CommandQueue(cl_ctx) from meshmode.mesh.generation import ( # noqa - generate_icosphere, generate_icosahedron) + generate_icosphere, generate_icosahedron, + generate_torus) #mesh = generate_icosphere(1, order=order) - mesh = generate_icosahedron(1, order=order) + #mesh = generate_icosahedron(1, order=order) + mesh = generate_torus(3, 1, order=order) from meshmode.discretization import Discretization from meshmode.discretization.poly_element import \ diff --git a/meshmode/discretization/connection.py b/meshmode/discretization/connection.py index b91b3fc..3fdd1db 100644 --- a/meshmode/discretization/connection.py +++ b/meshmode/discretization/connection.py @@ -420,4 +420,12 @@ def make_boundary_restriction(queue, discr, group_factory): # }}} + +# {{{ refinement connection + +def make_refinement_connection(refiner, coarse_discr): + pass + +# }}} + # vim: foldmethod=marker diff --git a/meshmode/mesh/generation.py b/meshmode/mesh/generation.py index 5df058f..6f3e76c 100644 --- a/meshmode/mesh/generation.py +++ b/meshmode/mesh/generation.py @@ -28,6 +28,33 @@ import numpy.linalg as la import modepy as mp +__doc__ = """ + +Curves +------ + +.. autofunction:: make_curve_mesh + +Curve parametrizations +^^^^^^^^^^^^^^^^^^^^^^ + +.. autofunction:: ellipse +.. autofunction:: cloverleaf +.. autofunction:: starfish +.. autofunction:: drop +.. autofunction:: n_gon +.. autofunction:: qbx_peanut + +Surfaces +-------- + +.. autofunction:: generate_icosahedron +.. autofunction:: generate_icosphere +.. autofunction:: generate_torus + +""" + + # {{{ test curve parametrizations def ellipse(aspect_ratio, t): @@ -138,34 +165,6 @@ def qbx_peanut(t): # }}} -def make_group_from_vertices(vertices, vertex_indices, order): - el_vertices = vertices[:, vertex_indices] - - el_origins = el_vertices[:, :, 0][:, :, np.newaxis] - # ambient_dim, nelements, nspan_vectors - spanning_vectors = ( - el_vertices[:, :, 1:] - el_origins) - - nspan_vectors = spanning_vectors.shape[-1] - dim = nspan_vectors - - # dim, nunit_nodes - unit_nodes = mp.warp_and_blend_nodes(dim, order) - unit_nodes_01 = 0.5 + 0.5*unit_nodes - - nodes = np.einsum( - "si,des->dei", - unit_nodes_01, spanning_vectors) + el_origins - - # make contiguous - nodes = nodes.copy() - - from meshmode.mesh import SimplexElementGroup - return SimplexElementGroup( - order, vertex_indices, nodes, - unit_nodes=unit_nodes) - - def make_curve_mesh(curve_f, element_boundaries, order): """ :arg curve_f: A callable representing a parametrization for a curve, @@ -207,6 +206,34 @@ def make_curve_mesh(curve_f, element_boundaries, order): element_connectivity=None) +def make_group_from_vertices(vertices, vertex_indices, order): + el_vertices = vertices[:, vertex_indices] + + el_origins = el_vertices[:, :, 0][:, :, np.newaxis] + # ambient_dim, nelements, nspan_vectors + spanning_vectors = ( + el_vertices[:, :, 1:] - el_origins) + + nspan_vectors = spanning_vectors.shape[-1] + dim = nspan_vectors + + # dim, nunit_nodes + unit_nodes = mp.warp_and_blend_nodes(dim, order) + unit_nodes_01 = 0.5 + 0.5*unit_nodes + + nodes = np.einsum( + "si,des->dei", + unit_nodes_01, spanning_vectors) + el_origins + + # make contiguous + nodes = nodes.copy() + + from meshmode.mesh import SimplexElementGroup + return SimplexElementGroup( + order, vertex_indices, nodes, + unit_nodes=unit_nodes) + + def generate_icosahedron(r, order): # http://en.wikipedia.org/w/index.php?title=Icosahedron&oldid=387737307 @@ -259,8 +286,6 @@ def generate_icosphere(r, order): def generate_torus_and_cycle_vertices(r_outer, r_inner, n_outer=20, n_inner=10, order=1): - raise NotImplementedError("not yet updated for meshmode") - a = r_outer b = r_inner u, v = np.mgrid[0:2*np.pi:2*np.pi/n_outer, 0:2*np.pi:2*np.pi/n_inner] @@ -269,82 +294,59 @@ def generate_torus_and_cycle_vertices(r_outer, r_inner, x = np.cos(u)*(a+b*np.cos(v)) y = np.sin(u)*(a+b*np.cos(v)) z = b*np.sin(v) - pts = (np.vstack((x[np.newaxis], y[np.newaxis], z[np.newaxis])) - .T.copy().reshape(-1, 3)) + vertices = (np.vstack((x[np.newaxis], y[np.newaxis], z[np.newaxis])) + .transpose(0, 2, 1).copy().reshape(3, -1)) def idx(i, j): return (i % n_outer) + (j % n_inner) * n_outer - tris = ([(idx(i, j), idx(i+1, j), idx(i, j+1)) + vertex_indices = ([(idx(i, j), idx(i+1, j), idx(i, j+1)) for i in xrange(n_outer) for j in xrange(n_inner)] + [(idx(i+1, j), idx(i+1, j+1), idx(i, j+1)) for i in xrange(n_outer) for j in xrange(n_inner)]) - from meshmode.mesh import Mesh - mesh = Mesh(pts, tris) - - if order > 1: - from meshmode.mesh.trianglemaps import interv_pts_on_unit - eq_nodes = interv_pts_on_unit(order, 0, 1) - - # indices: triangle #, node #, xyz axis - mapped_eq_nodes = np.empty((len(mesh), len(eq_nodes), 3)) - - for iel, el_nodes in enumerate(mesh.elements): - n1, n2, n3 = mesh.vertex_coordinates[el_nodes] - a1 = np.vstack([n2-n1, n3-n1]).T - b1 = n1 - - mapped_eq_nodes[iel] = np.dot(a1, eq_nodes.T).T + b1 - - mn = mapped_eq_nodes - major_theta = np.arctan2(mapped_eq_nodes[:, :, 1], - mapped_eq_nodes[:, :, 0]) - rvec = np.array([ - np.cos(major_theta), - np.sin(major_theta), - np.zeros_like(major_theta)]).transpose((1, 2, 0)) - - # ^ - # | - # --------------+----. - # / | \ - # / | _-- \ - # | |.^ | | y - # | +------+---> - # | x | - # \ / - # \ / - # ------------------' - - x = np.sum(mapped_eq_nodes*rvec, axis=-1) - a - - minor_theta = np.arctan2(mapped_eq_nodes[:, :, 2], x) - - mapped_eq_nodes[:, :, 0] = np.cos(major_theta)*(a+b*np.cos( - minor_theta)) - mapped_eq_nodes[:, :, 1] = np.sin(major_theta)*(a+b*np.cos( - minor_theta)) - mapped_eq_nodes[:, :, 2] = b*np.sin(minor_theta) - - #reshaped_nodes = mapped_eq_nodes.reshape(-1, 3) - reshaped_nodes = mn.reshape(-1, 3) + vertex_indices = np.array(vertex_indices, dtype=np.int32) + grp = make_group_from_vertices(vertices, vertex_indices, order) - mesh = Mesh( - vertex_coordinates=reshaped_nodes, - elements=np.arange(len(reshaped_nodes)).reshape(len(mesh), -1), - order=order) + # ambient_dim, nelements, nunit_nodes + nodes = grp.nodes.copy() + + major_theta = np.arctan2(nodes[1], nodes[0]) + rvec = np.array([ + np.cos(major_theta), + np.sin(major_theta), + np.zeros_like(major_theta)]) + + # ^ + # | + # --------------+----. + # / | \ + # / | _-- \ + # | |.^ | | y + # | +------+---> + # | x | + # \ / + # \ / + # ------------------' + + x = np.sum(nodes*rvec, axis=0) - a + + minor_theta = np.arctan2(nodes[2], x) + + nodes[0] = np.cos(major_theta)*(a+b*np.cos( + minor_theta)) + nodes[1] = np.sin(major_theta)*(a+b*np.cos( + minor_theta)) + nodes[2] = b*np.sin(minor_theta) - return mesh, \ - [idx(i, 0) for i in xrange(n_outer)], \ - [idx(0, j) for j in xrange(n_inner)] + from meshmode.mesh import Mesh + return (Mesh(vertices, [grp.copy(nodes=nodes)], element_connectivity=None), + [idx(i, 0) for i in xrange(n_outer)], + [idx(0, j) for j in xrange(n_inner)]) def generate_torus(r_outer, r_inner, n_outer=20, n_inner=10, order=1): - # FIXME - raise NotImplementedError("not yet updated for meshmode") - - geo, a_cycle, b_cycle = generate_torus_and_cycle_vertices( + mesh, a_cycle, b_cycle = generate_torus_and_cycle_vertices( r_outer, r_inner, n_outer, n_inner, order) - return geo + return mesh # vim: fdm=marker -- GitLab