def check_bc_coverage(self, mesh): from meshmode.mesh import check_bc_coverage check_bc_coverage(mesh, [ self.pec_tag, self.pmc_tag, self.absorb_tag, self.incident_tag])
def test_boundary_tags(): from meshmode.mesh.io import read_gmsh # ensure tags are read in mesh = read_gmsh('annulus.msh') if not {'outer_bdy', 'inner_bdy'} <= set(mesh.boundary_tags): print("Mesh boundary tags:", mesh.boundary_tags) raise ValueError('Tags not saved by mesh') # correct answers num_on_outer_bdy = 26 num_on_inner_bdy = 13 # check how many elements are marked on each boundary num_marked_outer_bdy = 0 num_marked_inner_bdy = 0 outer_btag_bit = mesh.boundary_tag_bit('outer_bdy') inner_btag_bit = mesh.boundary_tag_bit('inner_bdy') for igrp in range(len(mesh.groups)): bdry_fagrp = mesh.facial_adjacency_groups[igrp].get(None, None) if bdry_fagrp is None: continue for i, nbrs in enumerate(bdry_fagrp.neighbors): if (-nbrs) & outer_btag_bit: num_marked_outer_bdy += 1 if (-nbrs) & inner_btag_bit: num_marked_inner_bdy += 1 # raise errors if wrong number of elements marked if num_marked_inner_bdy != num_on_inner_bdy: raise ValueError("%i marked on inner boundary, should be %i" % (num_marked_inner_bdy, num_on_inner_bdy)) if num_marked_outer_bdy != num_on_outer_bdy: raise ValueError("%i marked on outer boundary, should be %i" % (num_marked_outer_bdy, num_on_outer_bdy)) # ensure boundary is covered from meshmode.mesh import check_bc_coverage check_bc_coverage(mesh, ['inner_bdy', 'outer_bdy'])
def check_bc_coverage(self, mesh): from meshmode.mesh import check_bc_coverage check_bc_coverage( mesh, [self.dirichlet_tag, self.neumann_tag, self.radiation_tag])
def test_bdy_tags(square_or_cube_mesh, bdy_ids, coord_indices, coord_values, only_convert_bdy): """ Make sure the given boundary ids cover the converted mesh. Make sure that the given coordinate have the given value for the corresponding boundary tag (see :mod:`firedrake.utility_meshes`'s documentation to see how the boundary tags for its utility meshes are defined) """ cells_to_use = None if only_convert_bdy: 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 assert {BTAG_ALL, BTAG_REALLY_ALL} <= set(mm_mesh.boundary_tags) # Check disjoint coverage of bdy ids and BTAG_ALL check_bc_coverage(mm_mesh, [BTAG_ALL]) check_bc_coverage(mm_mesh, bdy_ids) # count number of times the boundary tag appears in the meshmode mesh, # should be the same as in the firedrake mesh bdy_id_to_mm_count = {} # Now make sure we have identified the correct faces face_vertex_indices = mm_mesh.groups[0].face_vertex_indices() ext_grp = mm_mesh.facial_adjacency_groups[0][None] for iel, ifac, bdy_flags in zip(ext_grp.elements, ext_grp.element_faces, ext_grp.neighbors): # try: if mm_mesh has boundaries flagged as not boundaries we need to # skip them # catch: if mm_mesh does not use BTAG_INDUCED_BOUNDARY flag we get a # ValueError try: # If this facet is flagged as not really a boundary, skip it if mm_mesh.boundary_tag_bit(BTAG_INDUCED_BOUNDARY) & -bdy_flags: continue except ValueError: pass el_vert_indices = mm_mesh.groups[0].vertex_indices[iel] # numpy nb: have to have comma to use advanced indexing face_vert_indices = el_vert_indices[face_vertex_indices[ifac], ] # shape: *(ambient dim, num vertices on face)* face_verts = mm_mesh.vertices[:, face_vert_indices] # Figure out which coordinate should have a fixed value, and what # that value is. Also, count how many times each boundary tag appears coord_index, val = None, None for bdy_id_index, bdy_id in enumerate(bdy_ids): if mm_mesh.boundary_tag_bit(bdy_id) & -bdy_flags: bdy_id_to_mm_count.setdefault(bdy_id, 0) bdy_id_to_mm_count[bdy_id] += 1 coord_index = coord_indices[bdy_id_index] val = coord_values[bdy_id_index] break assert np.max(np.abs(face_verts[coord_index, :] - val)) < CLOSE_ATOL # Verify that the number of meshes tagged with a boundary tag # is the same in meshmode and firedrake for each tag in *bdy_ids* fdrake_bdy_ids, fdrake_counts = \ np.unique(square_or_cube_mesh.exterior_facets.markers, return_counts=True) assert set(fdrake_bdy_ids) == set(bdy_ids) for bdy_id, fdrake_count in zip(fdrake_bdy_ids, fdrake_counts): assert fdrake_count == bdy_id_to_mm_count[bdy_id]
def test_box_boundary_tags(dim, nelem, mesh_type, group_cls, visualize=False): if group_cls is TensorProductElementGroup and mesh_type is not None: pytest.skip("mesh type not supported on tensor product elements") from meshmode.mesh import is_boundary_tag_empty from meshmode.mesh import check_bc_coverage if dim == 1: a = (0, ) b = (1, ) nelements_per_axis = (nelem, ) btag_to_face = {"btag_test_1": ["+x"], "btag_test_2": ["-x"]} elif dim == 2: a = (0, -1) b = (1, 1) nelements_per_axis = (nelem, ) * 2 btag_to_face = { "btag_test_1": ["+x", "-y"], "btag_test_2": ["+y", "-x"] } elif dim == 3: a = (0, -1, -1) b = (1, 1, 1) nelements_per_axis = (nelem, ) * 3 btag_to_face = { "btag_test_1": ["+x", "-y", "-z"], "btag_test_2": ["+y", "-x", "+z"] } mesh = mgen.generate_regular_rect_mesh( a=a, b=b, nelements_per_axis=nelements_per_axis, order=3, boundary_tag_to_face=btag_to_face, group_cls=group_cls, mesh_type=mesh_type) if visualize and dim == 2: from meshmode.mesh.visualization import draw_2d_mesh draw_2d_mesh(mesh, draw_element_numbers=False, draw_vertex_numbers=False) import matplotlib.pyplot as plt plt.show() # correct answer if dim == 1: num_on_bdy = 1 elif group_cls is TensorProductElementGroup: num_on_bdy = dim * nelem**(dim - 1) elif group_cls is SimplexElementGroup: num_on_bdy = dim * (dim - 1) * nelem**(dim - 1) else: raise AssertionError() assert not is_boundary_tag_empty(mesh, "btag_test_1") assert not is_boundary_tag_empty(mesh, "btag_test_2") check_bc_coverage(mesh, ["btag_test_1", "btag_test_2"]) # check how many elements are marked on each boundary num_marked_bdy_1 = 0 num_marked_bdy_2 = 0 btag_1_bit = mesh.boundary_tag_bit("btag_test_1") btag_2_bit = mesh.boundary_tag_bit("btag_test_2") for igrp in range(len(mesh.groups)): bdry_fagrp = mesh.facial_adjacency_groups[igrp].get(None, None) if bdry_fagrp is None: continue for nbrs in bdry_fagrp.neighbors: if (-nbrs) & btag_1_bit: num_marked_bdy_1 += 1 if (-nbrs) & btag_2_bit: num_marked_bdy_2 += 1 # raise errors if wrong number of elements marked if num_marked_bdy_1 != num_on_bdy: raise ValueError("%i marked on custom boundary 1, should be %i" % (num_marked_bdy_1, num_on_bdy)) if num_marked_bdy_2 != num_on_bdy: raise ValueError("%i marked on custom boundary 2, should be %i" % (num_marked_bdy_2, num_on_bdy))