diff --git a/meshmode/discretization/connection/face.py b/meshmode/discretization/connection/face.py index 88d91d9e615a6102e9e891c76f5948186a7b5f6b..680d0686f906b33be2bbfc383b44390012aceba0 100644 --- a/meshmode/discretization/connection/face.py +++ b/meshmode/discretization/connection/face.py @@ -277,7 +277,7 @@ def make_face_restriction(discr, group_factory, boundary_tag, if ibface_face == face_id], dtype=np.intp) - # {{{ Preallocate arrays for mesh group + # {{{ preallocate arrays for mesh group nbatch_elements = len(batch_boundary_el_numbers_in_grp) diff --git a/meshmode/mesh/__init__.py b/meshmode/mesh/__init__.py index d3c9c8cfd11e4040ec7d507354776b9682f0fcae..44dba80ba98f90e6d9eb95a5803cd6fbaa083efb 100644 --- a/meshmode/mesh/__init__.py +++ b/meshmode/mesh/__init__.py @@ -288,10 +288,10 @@ class SimplexElementGroup(MeshElementGroup): ) elif self.dim == 3: return ( - (0, 1, 2), - (0, 3, 1), - (0, 2, 3), - (1, 3, 2) + (0, 2, 1), + (0, 1, 3), + (0, 3, 2), + (1, 2, 3) ) else: raise NotImplementedError("dim=%d" % self.dim) diff --git a/test/test_meshmode.py b/test/test_meshmode.py index 413a107d1a3d33b52b1a0fd2eea2047822db54ed..c8e28228fca44e1dfa8de5bd561e083b3ad5c9ab 100644 --- a/test/test_meshmode.py +++ b/test/test_meshmode.py @@ -41,6 +41,7 @@ from meshmode.discretization.poly_element import ( from meshmode.mesh import BTAG_ALL from meshmode.discretization.connection import \ FRESTR_ALL_FACES, FRESTR_INTERIOR_FACES +import meshmode.mesh.generation as mgen import pytest @@ -450,6 +451,66 @@ def test_element_orientation(): # }}} +# {{{ element orientation: canned 3D meshes + +# python test_meshmode.py 'test_sanity_balls(cl._csc, "disk-radius-1.step", 2, 2, visualize=True)' # noqa +@pytest.mark.parametrize(("what", "mesh_gen_func"), [ + ("ball", lambda: mgen.generate_icosahedron(1, 1)), + ("torus", lambda: mgen.generate_torus(5, 1)), + ]) +def test_3d_orientation(ctx_getter, what, mesh_gen_func, visualize=False): + pytest.importorskip("pytential") + + logging.basicConfig(level=logging.INFO) + + ctx = ctx_getter() + queue = cl.CommandQueue(ctx) + + mesh = mesh_gen_func() + + logger.info("%d elements" % mesh.nelements) + + from meshmode.discretization import Discretization + discr = Discretization(ctx, mesh, + PolynomialWarpAndBlendGroupFactory(1)) + + from pytential import bind, sym + + # {{{ check normals point outward + + if what == "torus": + nodes = sym.nodes(mesh.ambient_dim).as_vector() + angle = sym.atan2(nodes[1], nodes[0]) + center_nodes = sym.make_obj_array([ + 5*sym.cos(angle), + 5*sym.sin(angle), + 0*angle]) + normal_outward_expr = ( + sym.normal(mesh.ambient_dim) | (nodes-center_nodes)) + + else: + normal_outward_expr = ( + sym.normal(mesh.ambient_dim) | sym.nodes(mesh.ambient_dim)) + + normal_outward_check = bind(discr, normal_outward_expr)(queue).as_scalar() > 0 + + assert normal_outward_check.get().all(), normal_outward_check.get() + + # }}} + + normals = bind(discr, sym.normal(mesh.ambient_dim).xproject(1))(queue) + + if visualize: + from meshmode.discretization.visualization import make_visualizer + vis = make_visualizer(queue, discr, 1) + + vis.write_vtk_file("normals.vtu", [ + ("normals", normals), + ]) + +# }}} + + # {{{ merge and map def test_merge_and_map(ctx_getter, visualize=False): @@ -581,7 +642,6 @@ def test_sanity_single_element(ctx_getter, dim, order, visualize=False): ("bdry_normals", bdry_normals) ]) - from pytential import bind, sym normal_outward_check = bind(bdry_discr, sym.normal(dim) |