diff --git a/meshmode/interop/firedrake/connection.py b/meshmode/interop/firedrake/connection.py index 9b77453d60cd933c3c269a0c3b315d537c6dc9f9..5d560bb02a66a589321e3f2302eb9f7fab5a401d 100644 --- a/meshmode/interop/firedrake/connection.py +++ b/meshmode/interop/firedrake/connection.py @@ -73,8 +73,7 @@ def _reorder_nodes(orient, nodes, flip_matrix, unflip=False): np.dot(flip_mat, flip_mat) - np.eye(len(flip_mat))) < 1e-13 - # flip nodes that need to be flipped, note that this point we act - # like we are in a DG space + # flip nodes that need to be flipped flipped_nodes = np.copy(nodes) flipped_nodes[orient < 0] = np.einsum( "ij,ej->ei", @@ -561,6 +560,35 @@ class FiredrakeConnection: # {{{ Create connection from firedrake into meshmode +def _get_cells_to_use(fdrake_mesh, bdy_id): + """ + Return the cell indices of 'fdrake_mesh' which have at least one vertex + coinciding with a facet which is marked with firedrake marker + 'bdy_id'. + + If 'bdy_id' is *None*, returns *None* + + Separated into a function for testing purposes + + :param fdrake_mesh: A mesh as in + :func:`~meshmode.interop.firedrake.mesh.import_firedrake_mesh` + :param bdy_id: As the argument 'restrict_to_boundary' in + :func:`build_connection_from_firedrake` + """ + if bdy_id is None: + return None + + cfspace = fdrake_mesh.coordinates.function_space() + cell_node_list = cfspace.cell_node_list + + boundary_nodes = cfspace.boundary_nodes(bdy_id, 'topological') + # Reduce along each cell: Is a vertex of the cell in boundary nodes? + cell_is_near_bdy = np.any(np.isin(cell_node_list, boundary_nodes), axis=1) + + from pyop2.datatypes import IntType + return np.nonzero(cell_is_near_bdy)[0].astype(IntType) + + def build_connection_from_firedrake(actx, fdrake_fspace, grp_factory=None, restrict_to_boundary=None): @@ -651,18 +679,8 @@ PolynomialWarpAndBlendGroupFactory` is used. # If only converting a portion of the mesh near the boundary, get # *cells_to_use* as described in # :func:`meshmode.interop.firedrake.mesh.import_firedrake_mesh` - cells_to_use = None - if restrict_to_boundary is not None: - cfspace = fdrake_fspace.mesh().coordinates.function_space() - cell_node_list = cfspace.cell_node_list - - boundary_nodes = cfspace.boundary_nodes(restrict_to_boundary, - 'topological') - # Reduce along each cell: Is a vertex of the cell in boundary nodes? - cell_is_near_bdy = np.any(np.isin(cell_node_list, boundary_nodes), axis=1) - - from pyop2.datatypes import IntType - cells_to_use = np.nonzero(cell_is_near_bdy)[0].astype(IntType) + cells_to_use = _get_cells_to_use(fdrake_fspace.mesh(), + restrict_to_boundary) # Create to_discr mm_mesh, orient = import_firedrake_mesh(fdrake_fspace.mesh(), diff --git a/test/test_firedrake_interop.py b/test/test_firedrake_interop.py index 06e6c661122ac70c77c0dc5b04d25635ce6c5552..446d6eee4e5fa5e944881f4d3a53ba8dd90d851a 100644 --- a/test/test_firedrake_interop.py +++ b/test/test_firedrake_interop.py @@ -200,13 +200,14 @@ def test_to_fd_consistency(ctx_factory, mm_mesh, fspace_degree): # }}} -# {{{ Now check the FromBoundaryFiredrakeConnection consistency +# {{{ Now check the FiredrakeConnection consistency when restricted to bdy def test_from_boundary_consistency(ctx_factory, fdrake_mesh, fspace_degree): """ - Make basic checks that FiredrakeFromBoundaryConnection is not doing + Make basic checks that FiredrakeConnection restricted to cells + near the boundary is not doing something obviously wrong, i.e. that the firedrake boundary tags partition the converted meshmode mesh, that the firedrake boundary tags correspond to the same physical @@ -220,9 +221,10 @@ def test_from_boundary_consistency(ctx_factory, queue = cl.CommandQueue(cl_ctx) actx = PyOpenCLArrayContext(queue) - frombdy_conn = FromBoundaryFiredrakeConnection(actx, - fdrake_fspace, - "on_boundary") + frombdy_conn = \ + build_connection_from_firedrake(actx, + fdrake_fspace, + restrict_to_boundary="on_boundary") # Ensure the meshmode mesh has one group and make sure both # meshes agree on some basic properties @@ -244,7 +246,8 @@ def test_from_boundary_consistency(ctx_factory, fdrake_unit_vert_indices = np.array(fdrake_unit_vert_indices) # only look at cells "near" bdy (with >= 1 vertex on) - cells_near_bdy = frombdy_conn._get_cells_to_use(fdrake_mesh) + from meshmode.interop.firedrake.connection import _get_cells_to_use + cells_near_bdy = _get_cells_to_use(fdrake_mesh, 'on_boundary') # get the firedrake vertices of cells near the boundary, # in no particular order fdrake_vert_indices = \ @@ -304,11 +307,8 @@ def test_bdy_tags(square_or_cube_mesh, bdy_ids, coord_indices, coord_values, """ cells_to_use = None if only_convert_bdy: - # make a dummy connection which just has a bdy_id - class DummyConnection(FromBoundaryFiredrakeConnection): - def __init__(self): - self.bdy_id = 'on_boundary' - cells_to_use = DummyConnection()._get_cells_to_use(square_or_cube_mesh) + from meshmode.interop.firedrake.connection import _get_cells_to_use + cells_to_use = _get_cells_to_use(square_or_cube_mesh, 'on_boundary') mm_mesh, orient = import_firedrake_mesh(square_or_cube_mesh, cells_to_use=cells_to_use) # Ensure meshmode required boundary tags are there