diff --git a/meshmode/distributed.py b/meshmode/distributed.py index 529190b55e091b432298f442697e02c9b2786ddc..7ddaa8041725e7dede750955c3a5025ec0b835c4 100644 --- a/meshmode/distributed.py +++ b/meshmode/distributed.py @@ -40,6 +40,9 @@ TAG_SEND_BOUNDARY = TAG_BASE + 2 __doc__ = """ .. autoclass:: MPIMeshDistributor .. autoclass:: MPIBoundaryTransceiver + +.. autofunction:: get_partition_by_pymetis +.. autofunction:: get_connected_partitions """ @@ -207,10 +210,31 @@ class MPIBoundaryCommSetupHelper(object): # }}} -def get_connected_partitions(mesh): +def get_partition_by_pymetis(mesh, num_parts, **kwargs): + """Return a mesh partition created by :mod:`pymetis`. + + :arg mesh: A :class:`meshmode.mesh.Mesh` instance + :arg num_parts: the number of parts in the mesh partition + :arg kwargs: Passed unmodified to :func:`pymetis.part_graph`. + :returns: a :class:`numpy.ndarray` with one entry per element indicating + to which partition each element belongs, with entries between ``0`` and + ``num_parts-1``. """ - :arg mesh: A :class:`Mesh` - Returns the set of partition numbers that are connected to `mesh` + from pymetis import part_graph + _, p = part_graph(num_parts, + xadj=mesh.nodal_adjacency.neighbors_starts.tolist(), + adjncy=mesh.nodal_adjacency.neighbors.tolist(), + **kwargs) + + return np.array(p) + + +def get_connected_partitions(mesh): + """For a local mesh part in *mesh*, determine the set of numbers + of remote partitions to which this mesh piece is connected. + + :arg mesh: A :class:`meshmode.mesh.Mesh` instance + :returns: the set of partition numbers that are connected to `mesh` """ connected_parts = set() from meshmode.mesh import InterPartitionAdjacencyGroup @@ -221,4 +245,5 @@ def get_connected_partitions(mesh): adj[None].neighbor_partitions[indices]) return connected_parts + # vim: foldmethod=marker diff --git a/meshmode/mesh/__init__.py b/meshmode/mesh/__init__.py index 8ff2981e9a50e89c409654f81d36d2e6d8de1d13..58f765c0a821434e28b169456483e9d7d3bbf7f2 100644 --- a/meshmode/mesh/__init__.py +++ b/meshmode/mesh/__init__.py @@ -1236,7 +1236,8 @@ def as_python(mesh, function_name="make_mesh"): # {{{ check_bc_coverage -def check_bc_coverage(mesh, boundary_tags, incomplete_ok=False): +def check_bc_coverage(mesh, boundary_tags, incomplete_ok=False, + true_boundary_only=True): """Verify boundary condition coverage. Given a list of boundary tags as *boundary_tags*, this function verifies @@ -1247,6 +1248,7 @@ def check_bc_coverage(mesh, boundary_tags, incomplete_ok=False): :arg incomplete_ok: Do not report an error if some faces are not covered by the boundary conditions. + :arg true_boundary_only: only verify for faces tagged with :class:`BTAG_ALL`. """ for igrp, fagrp_map in enumerate(mesh.facial_adjacency_groups): @@ -1259,8 +1261,17 @@ def check_bc_coverage(mesh, boundary_tags, incomplete_ok=False): nb_el_bits = -nb_elements + # An array of flags for each face indicating whether we have encountered + # a boundary condition for that face. seen = np.zeros_like(nb_el_bits, dtype=np.bool) + if true_boundary_only: + tag_bit = mesh.boundary_tag_bit(BTAG_ALL) + tag_set = (nb_el_bits & tag_bit) != 0 + + # Consider non-boundary faces 'seen' + seen = seen | ~tag_set + for btag in boundary_tags: tag_bit = mesh.boundary_tag_bit(btag) tag_set = (nb_el_bits & tag_bit) != 0