Пример #1
0
def make_cylinder_mesh(radius=0.5, height=1, radial_subdivisions=10,
        height_subdivisions=1, max_volume=None, periodic=False,
        boundary_tagger=(lambda fvi, el, fn, all_v: [])):
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import make_cylinder

    points, facets, facet_holestarts, facet_markers = \
            make_cylinder(radius, height, radial_subdivisions,
                    height_subdivisions)

    assert len(facets) == len(facet_markers)

    if periodic:
        return _make_z_periodic_mesh(
                points, facets, facet_holestarts, facet_markers,
                height=height,
                max_volume=max_volume,
                boundary_tagger=boundary_tagger)
    else:
        mesh_info = MeshInfo()
        mesh_info.set_points(points)
        mesh_info.set_facets_ex(facets, facet_holestarts, facet_markers)

        generated_mesh = build(mesh_info, max_volume=max_volume)

        from hedge.mesh import make_conformal_mesh_ext
        from hedge.mesh.element import Tetrahedron

        vertices = numpy.asarray(generated_mesh.points, dtype=float, order="C")
        return make_conformal_mesh_ext(
                vertices,
                [Tetrahedron(i, el_idx, vertices)
                    for i, el_idx in enumerate(generated_mesh.elements)],
                boundary_tagger)
Пример #2
0
def make_1d_mesh(points, left_tag=None, right_tag=None, periodic=False,
        boundary_tagger=None, volume_tagger=None):

    def my_boundary_tagger(fvi, el, fn, all_v):
        if el.face_normals[fn][0] < 0:
            return [left_tag]
        else:
            return [right_tag]

    kwargs = {}
    if volume_tagger is not None:
        kwargs["volume_tagger"] = volume_tagger

    if periodic:
        left_tag = "x_minus"
        right_tag = "x_plus"

        kwargs["periodicity"] = [(left_tag, right_tag)]
        if boundary_tagger is not None:
            raise ValueError("cannot have both periodicity and a custom "
                    "boundary tagger")

        boundary_tagger = my_boundary_tagger
    else:
        boundary_tagger = boundary_tagger or my_boundary_tagger

    from hedge.mesh import make_conformal_mesh_ext
    vertices = numpy.asarray(points, order="C").reshape((len(points), 1))

    from hedge.mesh.element import Interval
    return make_conformal_mesh_ext(
            vertices,
            [Interval(i, (i, i+1), vertices) for i in xrange(len(points)-1)],
            boundary_tagger=boundary_tagger,
            **kwargs)
Пример #3
0
def make_disk_mesh(r=0.5, faces=50, max_area=4e-3,
        boundary_tagger=(lambda fvi, el, fn, all_v: [])):
    from math import cos, sin, pi

    def needs_refinement(vertices, area):
        return area > max_area

    points = [(r*cos(angle), r*sin(angle))
            for angle in numpy.linspace(0, 2*pi, faces, endpoint=False)]

    import meshpy.triangle as triangle

    mesh_info = triangle.MeshInfo()
    mesh_info.set_points(points)
    mesh_info.set_facets(
            list(_round_trip_connect(0, faces-1)),
            faces*[1]
            )

    generated_mesh = triangle.build(mesh_info, refinement_func=needs_refinement)

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Triangle
    vertices = numpy.asarray(generated_mesh.points, dtype=float, order="C")
    return make_conformal_mesh_ext(
            vertices,
            [Triangle(i, el_idx, vertices)
                for i, el_idx in enumerate(generated_mesh.elements)],
            boundary_tagger)
Пример #4
0
def make_mesh(a, b, pml_width=0.25, **kwargs):
    from meshpy.geometry import GeometryBuilder, make_circle
    geob = GeometryBuilder()

    circle_centers = [(-1.5, 0), (1.5, 0)]
    for cent in circle_centers:
        geob.add_geometry(*make_circle(1, cent))

    geob.wrap_in_box(1)
    geob.wrap_in_box(pml_width)

    mesh_mod = geob.mesher_module()
    mi = mesh_mod.MeshInfo()
    geob.set(mi)

    mi.set_holes(circle_centers)

    built_mi = mesh_mod.build(mi, **kwargs)

    def boundary_tagger(fvi, el, fn, points):
        return []

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Triangle
    pts = np.asarray(built_mi.points, dtype=np.float64)
    return make_conformal_mesh_ext(
            pts,
            [Triangle(i, el, pts)
                for i, el in enumerate(built_mi.elements)],
            boundary_tagger)
Пример #5
0
def make_mesh(a, b, pml_width=0.25, **kwargs):
    from meshpy.geometry import GeometryBuilder, make_circle
    geob = GeometryBuilder()

    circle_centers = [(-1.5, 0), (1.5, 0)]
    for cent in circle_centers:
        geob.add_geometry(*make_circle(1, cent))

    geob.wrap_in_box(1)
    geob.wrap_in_box(pml_width)

    mesh_mod = geob.mesher_module()
    mi = mesh_mod.MeshInfo()
    geob.set(mi)

    mi.set_holes(circle_centers)

    built_mi = mesh_mod.build(mi, **kwargs)

    def boundary_tagger(fvi, el, fn, points):
        return []

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Triangle
    pts = np.asarray(built_mi.points, dtype=np.float64)
    return make_conformal_mesh_ext(
        pts, [Triangle(i, el, pts) for i, el in enumerate(built_mi.elements)],
        boundary_tagger)
Пример #6
0
def finish_2d_rect_mesh(points, facets, facet_markers, marker2tag, refine_func,
        periodicity, boundary_tagger):
    """Semi-internal bottom-half routine for generation of rectangular 2D meshes."""
    import meshpy.triangle as triangle

    mesh_info = triangle.MeshInfo()
    mesh_info.set_points(points)
    mesh_info.set_facets(facets, facet_markers)

    #triangle.write_gnuplot_mesh("mesh.dat", mesh_info, True)

    if periodicity is None:
        periodicity = (False, False)

    axes = ["x", "y"]
    mesh_periodicity = []
    periodic_tags = set()
    for i, axis in enumerate(axes):
        if periodicity[i]:
            minus_tag = "minus_"+axis
            plus_tag = "plus_"+axis
            mesh_periodicity.append((minus_tag, plus_tag))
            periodic_tags.add(minus_tag)
            periodic_tags.add(plus_tag)
        else:
            mesh_periodicity.append(None)

    generated_mesh = triangle.build(mesh_info,
            refinement_func=refine_func,
            allow_boundary_steiner=not (periodicity[0] or periodicity[1]))

    fmlookup = MeshPyFaceMarkerLookup(generated_mesh)

    def wrapped_boundary_tagger(fvi, el, fn, all_v):
        btag = marker2tag[fmlookup(fvi)]
        if btag in periodic_tags:
            return [btag]
        else:
            return [btag] + boundary_tagger(fvi, el, fn, all_v)

    vertices = numpy.asarray(generated_mesh.points, dtype=float, order="C")

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Triangle
    return make_conformal_mesh_ext(
            vertices,
            [Triangle(i, el_idx, vertices)
                for i, el_idx in enumerate(generated_mesh.elements)],
            wrapped_boundary_tagger,
            periodicity=mesh_periodicity)
Пример #7
0
def _make_z_periodic_mesh(points, facets, facet_holestarts, facet_markers, height,
        max_volume, boundary_tagger):
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import Marker

    mesh_info = MeshInfo()
    mesh_info.set_points(points)
    mesh_info.set_facets_ex(facets, facet_holestarts, facet_markers)

    mesh_info.pbc_groups.resize(1)
    pbcg = mesh_info.pbc_groups[0]

    pbcg.facet_marker_1 = Marker.MINUS_Z
    pbcg.facet_marker_2 = Marker.PLUS_Z

    pbcg.set_transform(translation=[0, 0, height])

    def zper_boundary_tagger(fvi, el, fn, all_v):
        # we only ask about *boundaries*
        # we should not try to have the user tag
        # the (periodicity-induced) interior faces

        face_marker = fvi2fm[frozenset(fvi)]

        if face_marker == Marker.MINUS_Z:
            return ["minus_z"]
        if face_marker == Marker.PLUS_Z:
            return ["plus_z"]

        result = boundary_tagger(fvi, el, fn, all_v)
        if face_marker == Marker.SHELL:
            result.append("shell")
        return result

    generated_mesh = build(mesh_info, max_volume=max_volume)
    fvi2fm = generated_mesh.face_vertex_indices_to_face_marker

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Tetrahedron

    vertices = numpy.asarray(generated_mesh.points, dtype=float, order="C")
    return make_conformal_mesh_ext(
            vertices,
            [Tetrahedron(i, el_idx, vertices)
                for i, el_idx in enumerate(generated_mesh.elements)],
            zper_boundary_tagger,
            periodicity=[None, None, ("minus_z", "plus_z")])
Пример #8
0
def make_ball_mesh(r=0.5, subdivisions=10, max_volume=None,
        boundary_tagger=(lambda fvi, el, fn, all_v: [])):
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import make_ball

    points, facets, facet_holestarts, facet_markers = \
            make_ball(r, subdivisions)

    mesh_info = MeshInfo()

    mesh_info.set_points(points)
    mesh_info.set_facets_ex(facets, facet_holestarts, facet_markers)
    generated_mesh = build(mesh_info, max_volume=max_volume)

    vertices = numpy.asarray(generated_mesh.points, dtype=float, order="C")
    from hedge.mesh.element import Tetrahedron

    from hedge.mesh import make_conformal_mesh_ext
    return make_conformal_mesh_ext(
            vertices,
            [Tetrahedron(i, el_idx, vertices)
                for i, el_idx in enumerate(generated_mesh.elements)],
            boundary_tagger)
Пример #9
0
def make_extrusion_with_fine_core(rz,
                                  inner_r,
                                  max_volume_inner=1e-4,
                                  max_volume_outer=5e-2,
                                  radial_subdiv=20):

    min_z = min(rz_pt[1] for rz_pt in rz)
    max_z = max(rz_pt[1] for rz_pt in rz)

    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import generate_surface_of_revolution

    MINUS_Z_MARKER = 1
    PLUS_Z_MARKER = 2

    inner_points, inner_facets, inner_holes, inner_markers = \
            generate_surface_of_revolution(
                    [
                        (0, min_z),
                        (inner_r, min_z),
                        (inner_r, max_z),
                        (0, max_z),
                        ],
                    ring_markers=[
                        MINUS_Z_MARKER,
                        0,
                        PLUS_Z_MARKER
                        ],
                    radial_subdiv=radial_subdiv,
                    )

    inner_point_indices = tuple(range(len(inner_points)))

    outer_points, outer_facets, outer_holes, outer_markers = \
            generate_surface_of_revolution(
                    [(inner_r,min_z)] + rz + [(inner_r, max_z)],
                    ring_markers=[MINUS_Z_MARKER] + [0]*(len(rz)-1) + [PLUS_Z_MARKER],
                    point_idx_offset=len(inner_points),
                    radial_subdiv=radial_subdiv,
                    ring_point_indices=
                    [ inner_point_indices[:radial_subdiv] ]
                    + [None]*len(rz)
                    + [inner_point_indices[radial_subdiv:]]
                    )

    mesh_info = MeshInfo()
    mesh_info.set_points(inner_points + outer_points)
    mesh_info.set_facets_ex(
        inner_facets + outer_facets,
        inner_holes + outer_holes,
        inner_markers + outer_markers,
    )

    # set regional max. volume
    mesh_info.regions.resize(2)
    mesh_info.regions[0] = [0, 0, (max_z + min_z) / 2, 0, max_volume_inner]
    mesh_info.regions[1] = [
        inner_r + (rz[0][0] - inner_r) / 2, 0, (max_z + min_z) / 2, 0,
        max_volume_outer
    ]

    # add periodicity
    mesh_info.pbc_groups.resize(1)
    pbcg = mesh_info.pbc_groups[0]

    pbcg.facet_marker_1 = MINUS_Z_MARKER
    pbcg.facet_marker_2 = PLUS_Z_MARKER

    pbcg.set_transform(translation=[0, 0, max_z - min_z])

    mesh = build(mesh_info, verbose=True, volume_constraints=True)
    #print "%d elements" % len(mesh.elements)
    #mesh.write_vtk("gun.vtk")

    fvi2fm = mesh.face_vertex_indices_to_face_marker

    def zper_boundary_tagger(fvi, el, fn, points):
        face_marker = fvi2fm[frozenset(fvi)]
        if face_marker == MINUS_Z_MARKER:
            return ["minus_z"]
        elif face_marker == PLUS_Z_MARKER:
            return ["plus_z"]
        else:
            return ["shell"]

    vertices = numpy.asarray(mesh.points, dtype=float, order="C")

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Tetrahedron
    return make_conformal_mesh_ext(
        vertices, [
            Tetrahedron(i, el_idx, vertices)
            for i, el_idx in enumerate(mesh.elements)
        ],
        zper_boundary_tagger,
        periodicity=[None, None, ("minus_z", "plus_z")])
Пример #10
0
def make_extrusion_with_fine_core(rz, inner_r,
        max_volume_inner=1e-4, max_volume_outer=5e-2,
        radial_subdiv=20):

    min_z = min(rz_pt[1] for rz_pt in rz)
    max_z = max(rz_pt[1] for rz_pt in rz)

    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import generate_surface_of_revolution

    MINUS_Z_MARKER = 1
    PLUS_Z_MARKER = 2

    inner_points, inner_facets, inner_holes, inner_markers = \
            generate_surface_of_revolution(
                    [
                        (0, min_z),
                        (inner_r, min_z),
                        (inner_r, max_z),
                        (0, max_z),
                        ],
                    ring_markers=[
                        MINUS_Z_MARKER,
                        0,
                        PLUS_Z_MARKER
                        ],
                    radial_subdiv=radial_subdiv,
                    )

    inner_point_indices = tuple(range(len(inner_points)))

    outer_points, outer_facets, outer_holes, outer_markers = \
            generate_surface_of_revolution(
                    [(inner_r,min_z)] + rz + [(inner_r, max_z)],
                    ring_markers=[MINUS_Z_MARKER] + [0]*(len(rz)-1) + [PLUS_Z_MARKER],
                    point_idx_offset=len(inner_points),
                    radial_subdiv=radial_subdiv,
                    ring_point_indices=
                    [ inner_point_indices[:radial_subdiv] ]
                    + [None]*len(rz)
                    + [inner_point_indices[radial_subdiv:]]
                    )


    mesh_info = MeshInfo()
    mesh_info.set_points(inner_points + outer_points)
    mesh_info.set_facets_ex(
            inner_facets + outer_facets,
            inner_holes + outer_holes,
            inner_markers + outer_markers,
            )

    # set regional max. volume
    mesh_info.regions.resize(2)
    mesh_info.regions[0] = [0, 0, (max_z+min_z)/2, 0,
            max_volume_inner]
    mesh_info.regions[1] = [inner_r+(rz[0][0]-inner_r)/2, 0, (max_z+min_z)/2, 0,
            max_volume_outer]

    # add periodicity
    mesh_info.pbc_groups.resize(1)
    pbcg = mesh_info.pbc_groups[0]

    pbcg.facet_marker_1 = MINUS_Z_MARKER
    pbcg.facet_marker_2 = PLUS_Z_MARKER

    pbcg.set_transform(translation=[0,0,max_z-min_z])

    mesh = build(mesh_info, verbose=True, volume_constraints=True)
    #print "%d elements" % len(mesh.elements)
    #mesh.write_vtk("gun.vtk")

    fvi2fm = mesh.face_vertex_indices_to_face_marker

    def zper_boundary_tagger(fvi, el, fn, points):
        face_marker = fvi2fm[frozenset(fvi)]
        if face_marker == MINUS_Z_MARKER:
            return ["minus_z"]
        elif face_marker == PLUS_Z_MARKER:
            return ["plus_z"]
        else:
            return ["shell"]

    vertices = numpy.asarray(mesh.points, dtype=float, order="C")

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Tetrahedron
    return make_conformal_mesh_ext(
            vertices,
            [Tetrahedron(i, el_idx, vertices)
                for i, el_idx in enumerate(mesh.elements)],
            zper_boundary_tagger,
            periodicity=[None, None, ("minus_z", "plus_z")])
Пример #11
0
    def build_mesh(self,
                   periodicity,
                   allow_internal_boundaries,
                   tag_mapper,
                   boundary_tagger=None):
        # figure out dimensionalities
        vol_dim = max(
            el.el_type.dimensions
            for key, el in self.gmsh_vertex_nrs_to_element.iteritems())

        vol_elements = [
            el for key, el in self.gmsh_vertex_nrs_to_element.iteritems()
            if el.el_type.dimensions == vol_dim
        ]

        # build hedge-compatible elements
        from hedge.mesh.element import TO_CURVED_CLASS

        hedge_vertices = []
        hedge_elements = []

        gmsh_node_nr_to_hedge_vertex_nr = {}
        hedge_el_to_gmsh_element = {}

        def get_vertex_nr(gmsh_node_nr):
            try:
                return gmsh_node_nr_to_hedge_vertex_nr[gmsh_node_nr]
            except KeyError:
                hedge_vertex_nr = len(hedge_vertices)
                hedge_vertices.append(self.nodes[gmsh_node_nr])
                gmsh_node_nr_to_hedge_vertex_nr[gmsh_node_nr] = hedge_vertex_nr
                return hedge_vertex_nr

        for el_nr, gmsh_el in enumerate(vol_elements):
            el_map = LocalToGlobalMap(
                [self.nodes[ni] for ni in gmsh_el.node_indices],
                gmsh_el.el_type)
            is_affine = el_map.is_affine()

            el_class = gmsh_el.el_type.geometry
            if not is_affine:
                try:
                    el_class = TO_CURVED_CLASS[el_class]
                except KeyError:
                    raise NotImplementedError(
                        "unsupported curved gmsh element type %s" % el_class)

            vertex_indices = [
                get_vertex_nr(gmsh_node_nr)
                for gmsh_node_nr in gmsh_el.gmsh_vertex_indices
            ]

            if is_affine:
                hedge_el = el_class(el_nr, vertex_indices, hedge_vertices)
            else:
                hedge_el = el_class(el_nr, vertex_indices, el_map)

            hedge_elements.append(hedge_el)
            hedge_el_to_gmsh_element[hedge_el] = gmsh_el

        from pytools import reverse_dictionary
        hedge_vertex_nr_to_gmsh_node_nr = reverse_dictionary(
            gmsh_node_nr_to_hedge_vertex_nr)

        del vol_elements

        def volume_tagger(el, all_v):
            return [
                self.tag_name_map[tag_nr, el.dimensions]
                for tag_nr in hedge_el_to_gmsh_element[el].tag_numbers
                if (tag_nr, el.dimensions) in self.tag_name_map
            ]

        if boundary_tagger is None:

            def boundary_tagger(fvi, el, fn, all_v):
                gmsh_vertex_nrs = frozenset(
                    hedge_vertex_nr_to_gmsh_node_nr[face_vertex_index]
                    for face_vertex_index in fvi)

                try:
                    gmsh_element = self.gmsh_vertex_nrs_to_element[
                        gmsh_vertex_nrs]
                except KeyError:
                    return []
                else:
                    x = [
                        self.tag_name_map[tag_nr, el.dimensions - 1]
                        for tag_nr in gmsh_element.tag_numbers
                        if (tag_nr, el.dimensions - 1) in self.tag_name_map
                    ]
                    if len(x) > 1:
                        from pudb import set_trace
                        set_trace()
                    return x

        vertex_array = np.array(hedge_vertices, dtype=np.float64)
        pt_dim = vertex_array.shape[-1]
        if pt_dim != vol_dim:
            from warnings import warn
            warn("Found %d-dimensional mesh embedded in %d-dimensional space. "
                 "Hedge only supports meshes of zero codimension (for now). "
                 "Maybe you want to set force_dimension=%d?" %
                 (vol_dim, pt_dim, vol_dim))

        from hedge.mesh import make_conformal_mesh_ext
        return make_conformal_mesh_ext(
            vertex_array,
            hedge_elements,
            boundary_tagger=boundary_tagger,
            volume_tagger=volume_tagger,
            periodicity=periodicity,
            allow_internal_boundaries=allow_internal_boundaries)
Пример #12
0
    def build_mesh(self):
        # figure out dimensionalities
        node_dim = single_valued(len(node) for node in nodes)
        vol_dim = max(el.el_type.dimensions for key, el in gmsh_vertex_nrs_to_element.iteritems())
        bdry_dim = vol_dim - 1

        vol_elements = [el for key, el in gmsh_vertex_nrs_to_element.iteritems() if el.el_type.dimensions == vol_dim]
        bdry_elements = [el for key, el in gmsh_vertex_nrs_to_element.iteritems() if el.el_type.dimensions == bdry_dim]

        # build hedge-compatible elements
        from hedge.mesh.element import TO_CURVED_CLASS

        hedge_vertices = []
        hedge_elements = []

        gmsh_node_nr_to_hedge_vertex_nr = {}
        hedge_el_to_gmsh_element = {}

        def get_vertex_nr(gmsh_node_nr):
            try:
                return gmsh_node_nr_to_hedge_vertex_nr[gmsh_node_nr]
            except KeyError:
                hedge_vertex_nr = len(hedge_vertices)
                hedge_vertices.append(nodes[gmsh_node_nr])
                gmsh_node_nr_to_hedge_vertex_nr[gmsh_node_nr] = hedge_vertex_nr
                return hedge_vertex_nr

        for el_nr, gmsh_el in enumerate(vol_elements):
            el_map = LocalToGlobalMap([nodes[ni] for ni in gmsh_el.node_indices], gmsh_el.el_type)
            is_affine = el_map.is_affine()

            el_class = gmsh_el.el_type.geometry
            if not is_affine:
                try:
                    el_class = TO_CURVED_CLASS[el_class]
                except KeyError:
                    raise GmshFileFormatError("unsupported curved element type %s" % el_class)

            vertex_indices = [get_vertex_nr(gmsh_node_nr) for gmsh_node_nr in gmsh_el.gmsh_vertex_indices]

            if is_affine:
                hedge_el = el_class(el_nr, vertex_indices, hedge_vertices)
            else:
                hedge_el = el_class(el_nr, vertex_indices, el_map)

            hedge_elements.append(hedge_el)
            hedge_el_to_gmsh_element[hedge_el] = gmsh_el

        from pytools import reverse_dictionary

        hedge_vertex_nr_to_gmsh_node_nr = reverse_dictionary(gmsh_node_nr_to_hedge_vertex_nr)

        del vol_elements

        def volume_tagger(el, all_v):
            return [
                tag_name_map[tag_nr, el.dimensions]
                for tag_nr in hedge_el_to_gmsh_element[el].tag_numbers
                if (tag_nr, el.dimensions) in tag_name_map
            ]

        def boundary_tagger(fvi, el, fn, all_v):
            gmsh_vertex_nrs = frozenset(hedge_vertex_nr_to_gmsh_node_nr[face_vertex_index] for face_vertex_index in fvi)

            try:
                gmsh_element = gmsh_vertex_nrs_to_element[gmsh_vertex_nrs]
            except KeyError:
                return []
            else:
                x = [
                    tag_name_map[tag_nr, el.dimensions - 1]
                    for tag_nr in gmsh_element.tag_numbers
                    if (tag_nr, el.dimensions - 1) in tag_name_map
                ]
                if len(x) > 1:
                    from pudb import set_trace

                    set_trace()
                return x

        vertex_array = np.array(hedge_vertices, dtype=np.float64)
        pt_dim = vertex_array.shape[-1]
        if pt_dim != vol_dim:
            from warnings import warn

            warn(
                "Found %d-dimensional mesh embedded in %d-dimensional space. "
                "Hedge only supports meshes of zero codimension (for now). "
                "Maybe you want to set force_dimension=%d?" % (vol_dim, pt_dim, vol_dim)
            )

        from hedge.mesh import make_conformal_mesh_ext

        return make_conformal_mesh_ext(
            vertex_array,
            hedge_elements,
            boundary_tagger=boundary_tagger,
            volume_tagger=volume_tagger,
            periodicity=periodicity,
            allow_internal_boundaries=allow_internal_boundaries,
        )
Пример #13
0
def make_squaremesh():
    def round_trip_connect(seq):
        result = []
        for i in range(len(seq)):
            result.append((i, (i+1)%len(seq)))
        return result

    def needs_refinement(vertices, area):
        x =  sum(numpy.array(v) for v in vertices)/3

        max_area_volume = 0.7e-2 + 0.03*(0.05*x[1]**2 + 0.3*min(x[0]+1,0)**2)

        max_area_corners = 1e-3 + 0.001*max(
                la.norm(x-corner)**4 for corner in obstacle_corners)

        return bool(area > 2.5*min(max_area_volume, max_area_corners))

    from meshpy.geometry import make_box
    points, facets, _, _ = make_box((-0.5,-0.5), (0.5,0.5))
    obstacle_corners = points[:]

    from meshpy.geometry import GeometryBuilder, Marker

    profile_marker = Marker.FIRST_USER_MARKER
    builder = GeometryBuilder()
    builder.add_geometry(points=points, facets=facets,
            facet_markers=profile_marker)

    points, facets, _, facet_markers = make_box((-16, -22), (25, 22))
    builder.add_geometry(points=points, facets=facets,
            facet_markers=facet_markers)

    from meshpy.triangle import MeshInfo, build
    mi = MeshInfo()
    builder.set(mi)
    mi.set_holes([(0,0)])

    mesh = build(mi, refinement_func=needs_refinement,
            allow_boundary_steiner=True,
            generate_faces=True)

    print "%d elements" % len(mesh.elements)

    from meshpy.triangle import write_gnuplot_mesh
    write_gnuplot_mesh("mesh.dat", mesh)

    fvi2fm = mesh.face_vertex_indices_to_face_marker

    face_marker_to_tag = {
            profile_marker: "noslip",
            Marker.MINUS_X: "inflow",
            Marker.PLUS_X: "outflow",
            Marker.MINUS_Y: "inflow",
            Marker.PLUS_Y: "inflow"
            }

    def bdry_tagger(fvi, el, fn, all_v):
        face_marker = fvi2fm[fvi]
        return [face_marker_to_tag[face_marker]]

    from hedge.mesh import make_conformal_mesh_ext
    vertices = numpy.asarray(mesh.points, dtype=float, order="C")
    from hedge.mesh.element import Triangle
    return make_conformal_mesh_ext(
            vertices,
            [Triangle(i, el_idx, vertices)
                for i, el_idx in enumerate(mesh.elements)],
            bdry_tagger)
Пример #14
0
def make_nacamesh():
    def round_trip_connect(seq):
        result = []
        for i in range(len(seq)):
            result.append((i, (i + 1) % len(seq)))
        return result

    pt_back = numpy.array([1, 0])

    # def max_area(pt):
    # max_area_front = 1e-2*la.norm(pt)**2 + 1e-5
    # max_area_back = 1e-2*la.norm(pt-pt_back)**2 + 1e-4
    # return min(max_area_front, max_area_back)

    def max_area(pt):
        x = pt[0]

        if x < 0:
            return 1e-2 * la.norm(pt) ** 2 + 1e-5
        elif x > 1:
            return 1e-2 * la.norm(pt - pt_back) ** 2 + 1e-5
        else:
            return 1e-2 * pt[1] ** 2 + 1e-5

    def needs_refinement(vertices, area):
        barycenter = sum(numpy.array(v) for v in vertices) / 3
        return bool(area > max_area(barycenter))

    from meshpy.naca import get_naca_points

    points = get_naca_points(naca_digits="2412", number_of_points=80)

    from meshpy.geometry import GeometryBuilder, Marker
    from meshpy.triangle import write_gnuplot_mesh

    profile_marker = Marker.FIRST_USER_MARKER
    builder = GeometryBuilder()
    builder.add_geometry(points=points, facets=round_trip_connect(points), facet_markers=profile_marker)
    builder.wrap_in_box(4, (10, 8))

    from meshpy.triangle import MeshInfo, build

    mi = MeshInfo()
    builder.set(mi)
    mi.set_holes([builder.center()])

    mesh = build(
        mi,
        refinement_func=needs_refinement,
        # allow_boundary_steiner=False,
        generate_faces=True,
    )

    write_gnuplot_mesh("mesh.dat", mesh)

    print "%d elements" % len(mesh.elements)

    fvi2fm = mesh.face_vertex_indices_to_face_marker

    face_marker_to_tag = {
        profile_marker: "noslip",
        Marker.MINUS_X: "inflow",
        Marker.PLUS_X: "outflow",
        Marker.MINUS_Y: "inflow",
        Marker.PLUS_Y: "inflow"
        # Marker.MINUS_Y: "minus_y",
        # Marker.PLUS_Y: "plus_y"
    }

    def bdry_tagger(fvi, el, fn, all_v):
        face_marker = fvi2fm[fvi]
        return [face_marker_to_tag[face_marker]]

    from hedge.mesh import make_conformal_mesh_ext

    vertices = numpy.asarray(mesh.points, order="C")
    from hedge.mesh.element import Triangle

    return make_conformal_mesh_ext(
        vertices,
        [Triangle(i, el_idx, vertices) for i, el_idx in enumerate(mesh.elements)],
        bdry_tagger,
        # periodicity=[None, ("minus_y", "plus_y")]
    )
Пример #15
0
def parse_gmsh(line_iterable, force_dimension=None, periodicity=None,
        allow_internal_boundaries=False, tag_mapper=lambda tag: tag):
    """
    :param force_dimension: if not None, truncate point coordinates to this many dimensions.
    """

    feeder = LineFeeder(line_iterable)
    element_type_map = GMSH_ELEMENT_TYPE_TO_INFO_MAP

    # collect the mesh information
    nodes = []
    elements = []

    # maps (tag_number, dimension) -> tag_name
    tag_name_map = {}

    gmsh_vertex_nrs_to_element = {}

    class ElementInfo(Record):
        pass

    while feeder.has_next_line():
        next_line = feeder.get_next_line()
        if not next_line.startswith("$"):
            raise GmshFileFormatError("expected start of section, '%s' found instead" % next_line)

        section_name = next_line[1:]

        if section_name == "MeshFormat":
            line_count = 0
            while True:
                next_line = feeder.get_next_line()
                if next_line == "$End"+section_name:
                    break

                if line_count == 0:
                    version_number, file_type, data_size = next_line.split()

                if line_count > 0:
                    raise GmshFileFormatError("more than one line found in MeshFormat section")

                if version_number not in ["2.1", "2.2"]:
                    from warnings import warn
                    warn("unexpected mesh version number '%s' found" % version_number)

                if file_type != "0":
                    raise GmshFileFormatError("only ASCII gmsh file type is supported")

                line_count += 1

        elif section_name == "Nodes":
            node_count = int(feeder.get_next_line())
            node_idx = 1

            while True:
                next_line = feeder.get_next_line()
                if next_line == "$End"+section_name:
                    break

                parts = next_line.split()
                if len(parts) != 4:
                    raise GmshFileFormatError("expected four-component line in $Nodes section")

                read_node_idx = int(parts[0])
                if read_node_idx != node_idx:
                    raise GmshFileFormatError("out-of-order node index found")

                if force_dimension is not None:
                    point = [float(x) for x in parts[1:force_dimension+1]]
                else:
                    point = [float(x) for x in parts[1:]]

                nodes.append(numpy.array(point, dtype=numpy.float64))

                node_idx += 1

            if node_count+1 != node_idx:
                raise GmshFileFormatError("unexpected number of nodes found")

        elif section_name == "Elements":
            element_count = int(feeder.get_next_line())
            element_idx = 1
            while True:
                next_line = feeder.get_next_line()
                if next_line == "$End"+section_name:
                    break

                parts = [int(x) for x in next_line.split()]

                if len(parts) < 4:
                    raise GmshFileFormatError("too few entries in element line")

                read_element_idx = parts[0]
                if read_element_idx != element_idx:
                    raise GmshFileFormatError("out-of-order node index found")

                el_type_num = parts[1]
                try:
                    element_type = element_type_map[el_type_num]
                except KeyError:
                    raise GmshFileFormatError("unexpected element type %d"
                            % el_type_num)

                tag_count = parts[2]
                tags = parts[3:3+tag_count]

                # convert to zero-based
                node_indices = [x-1 for x in parts[3+tag_count:]]

                if element_type.node_count()!= len(node_indices):
                    raise GmshFileFormatError("unexpected number of nodes in element")

                gmsh_vertex_nrs = node_indices[:element_type.vertex_count]
                zero_based_idx = element_idx - 1
                el_info = ElementInfo(
                    index=zero_based_idx,
                    el_type=element_type,
                    node_indices=node_indices,
                    gmsh_vertex_indices=gmsh_vertex_nrs,
                    tag_numbers=[tag for tag in tags[:1] if tag != 0])

                gmsh_vertex_nrs_to_element[frozenset(gmsh_vertex_nrs)] = el_info
                element_idx +=1
            if element_count+1 != element_idx:
                raise GmshFileFormatError("unexpected number of elements found")

        elif section_name == "PhysicalNames":
            name_count = int(feeder.get_next_line())
            name_idx = 1

            while True:
                next_line = feeder.get_next_line()
                if next_line == "$End"+section_name:
                    break

                dimension, number, name = next_line.split(" ", 2)
                dimension = int(dimension)
                number = int(number)

                if not name[0] == '"' or not name[-1] == '"':
                    raise GmshFileFormatError("expected quotes around physical name")

                tag_name_map[number, dimension] = tag_mapper(name[1:-1])

                name_idx +=1

            if name_count+1 != name_idx:
                raise GmshFileFormatError("unexpected number of physical names found")
        else:
            # unrecognized section, skip
            while True:
                next_line = feeder.get_next_line()
                if next_line == "$End"+section_name:
                    break

    # figure out dimensionalities
    node_dim = single_valued(len(node) for node in nodes)
    vol_dim = max(el.el_type.dimensions for key, el in
            gmsh_vertex_nrs_to_element.iteritems() )
    bdry_dim = vol_dim - 1

    vol_elements = [el for key, el in gmsh_vertex_nrs_to_element.iteritems()
            if el.el_type.dimensions == vol_dim]
    bdry_elements = [el for key, el in gmsh_vertex_nrs_to_element.iteritems()
            if el.el_type.dimensions == bdry_dim]

    # build hedge-compatible elements
    from hedge.mesh.element import TO_CURVED_CLASS

    hedge_vertices = []
    hedge_elements = []

    gmsh_node_nr_to_hedge_vertex_nr = {}
    hedge_el_to_gmsh_element = {}

    def get_vertex_nr(gmsh_node_nr):
        try:
            return gmsh_node_nr_to_hedge_vertex_nr[gmsh_node_nr]
        except KeyError:
            hedge_vertex_nr = len(hedge_vertices)
            hedge_vertices.append(nodes[gmsh_node_nr])
            gmsh_node_nr_to_hedge_vertex_nr[gmsh_node_nr] = hedge_vertex_nr
            return hedge_vertex_nr

    for el_nr, gmsh_el in enumerate(vol_elements):
        el_map = LocalToGlobalMap(
                [nodes[ni] for ni in  gmsh_el.node_indices],
                gmsh_el.el_type)
        is_affine = el_map.is_affine()

        el_class = gmsh_el.el_type.geometry
        if not is_affine:
            try:
                el_class = TO_CURVED_CLASS[el_class]
            except KeyError:
                raise GmshFileFormatError("unsupported curved element type %s" % el_class)

        vertex_indices = [get_vertex_nr(gmsh_node_nr)
                for gmsh_node_nr in gmsh_el.gmsh_vertex_indices]

        if is_affine:
            hedge_el = el_class(el_nr, vertex_indices, hedge_vertices)
        else:
            hedge_el = el_class(el_nr, vertex_indices, el_map)

        hedge_elements.append(hedge_el)
        hedge_el_to_gmsh_element[hedge_el] = gmsh_el

    from pytools import reverse_dictionary
    hedge_vertex_nr_to_gmsh_node_nr = reverse_dictionary(
            gmsh_node_nr_to_hedge_vertex_nr)

    del vol_elements

    def volume_tagger(el, all_v):
        return [tag_name_map[tag_nr, el.dimensions]
                for tag_nr in hedge_el_to_gmsh_element[el].tag_numbers
                if (tag_nr, el.dimensions) in tag_name_map]

    def boundary_tagger(fvi, el, fn, all_v):
        gmsh_vertex_nrs = frozenset(
                hedge_vertex_nr_to_gmsh_node_nr[face_vertex_index]
                for face_vertex_index in fvi)

        try:
            gmsh_element = gmsh_vertex_nrs_to_element[gmsh_vertex_nrs]
        except KeyError:
            return []
        else:
            x = [tag_name_map[tag_nr, el.dimensions-1]
                    for tag_nr in gmsh_element.tag_numbers
                    if (tag_nr, el.dimensions-1) in tag_name_map]
            if len(x) > 1:
                from pudb import set_trace; set_trace()
            return x

    vertex_array = numpy.array(hedge_vertices, dtype=numpy.float64)
    pt_dim = vertex_array.shape[-1]
    if pt_dim != vol_dim:
        from warnings import warn
        warn("Found %d-dimensional mesh embedded in %d-dimensional space. "
                "Hedge only supports meshes of zero codimension (for now). "
                "Maybe you want to set force_dimension=%d?"
                % (vol_dim, pt_dim, vol_dim))

    from hedge.mesh import make_conformal_mesh_ext
    return make_conformal_mesh_ext(
            vertex_array,
            hedge_elements,
            boundary_tagger=boundary_tagger,
            volume_tagger=volume_tagger,
            periodicity=periodicity,
            allow_internal_boundaries=allow_internal_boundaries)
Пример #16
0
def make_box_mesh(a=(0, 0, 0), b=(1, 1, 1),
        max_volume=None, periodicity=None,
        boundary_tagger=(lambda fvi, el, fn, all_v: []),
        return_meshpy_mesh=False):
    """Return a mesh for a brick from the origin to `dimensions`.

    *max_volume* specifies the maximum volume for each tetrahedron.
    *periodicity* is either None, or a triple of bools, indicating
    whether periodic BCs are to be applied along that axis.
    See :func:`make_conformal_mesh` for the meaning of *boundary_tagger*.

    A few stock boundary tags are provided for easy application
    of boundary conditions, namely plus_[xyz] and minus_[xyz] tag
    the appropriate faces of the brick.
    """

    def count(iterable):
        result = 0
        for i in iterable:
            result += 1
        return result

    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import make_box

    points, facets, _, facet_markers = make_box(a, b)

    mesh_info = MeshInfo()
    mesh_info.set_points(points)
    mesh_info.set_facets(facets, facet_markers)

    if periodicity is None:
        periodicity = (False, False, False)

    axes = ["x", "y", "z"]

    per_count = count(p for p in periodicity if p)

    marker_to_tag = {}
    mesh_periodicity = []
    periodic_tags = set()

    if per_count:
        mesh_info.pbc_groups.resize(per_count)
    pbc_group_number = 0
    for axis, axis_per in enumerate(periodicity):
        minus_marker = 1+2*axis
        plus_marker = 2+2*axis

        minus_tag = "minus_"+axes[axis]
        plus_tag = "plus_"+axes[axis]

        marker_to_tag[minus_marker] = minus_tag
        marker_to_tag[plus_marker] = plus_tag

        if axis_per:
            pbcg = mesh_info.pbc_groups[pbc_group_number]
            pbc_group_number += 1

            pbcg.facet_marker_1 = minus_marker
            pbcg.facet_marker_2 = plus_marker

            translation = [0, 0, 0]
            translation[axis] = b[axis]-a[axis]
            pbcg.set_transform(translation=translation)

            mesh_periodicity.append((minus_tag, plus_tag))
            periodic_tags.add(minus_tag)
            periodic_tags.add(plus_tag)
        else:
            mesh_periodicity.append(None)

    generated_mesh = build(mesh_info, max_volume=max_volume)

    fvi2fm = generated_mesh.face_vertex_indices_to_face_marker

    def wrapped_boundary_tagger(fvi, el, fn, all_v):
        face_tag = marker_to_tag[fvi2fm[frozenset(fvi)]]

        if face_tag in periodic_tags:
            return [face_tag]
        else:
            return [face_tag] + boundary_tagger(fvi, el, fn, all_v)

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Tetrahedron
    vertices = numpy.asarray(generated_mesh.points, dtype=float, order="C")
    result = make_conformal_mesh_ext(
            vertices,
            [Tetrahedron(i, el_idx, vertices)
                for i, el_idx in enumerate(generated_mesh.elements)],
            wrapped_boundary_tagger,
            periodicity=mesh_periodicity)

    if return_meshpy_mesh:
        return result, generated_mesh
    else:
        return result
Пример #17
0
def make_centered_regular_rect_mesh(a=(0, 0), b=(1, 1), n=(5, 5), periodicity=None,
        post_refine_factor=1, boundary_tagger=(lambda fvi, el, fn, all_v: [])):
    """Create a semi-structured rectangular mesh.

    :param a: the lower left hand point of the rectangle
    :param b: the upper right hand point of the rectangle
    :param n: a tuple of integers indicating the total number of points
      on [a,b].
    :param periodicity: either None, or a tuple of bools specifying whether
      the mesh is to be periodic in x and y.
    """
    if min(n) < 2:
        raise ValueError("need at least two points in each direction")

    node_dict = {}
    centered_node_dict = {}
    points = []
    points_1d = [numpy.linspace(a_i, b_i, n_i)
            for a_i, b_i, n_i in zip(a, b, n)]
    dx = (numpy.array(b, dtype=numpy.float64)
            - numpy.array(a, dtype=numpy.float64)) / (numpy.array(n)-1)
    half_dx = dx/2

    for j in range(n[1]):
        for i in range(n[0]):
            node_dict[i, j] = len(points)
            points.append(numpy.array([points_1d[0][i], points_1d[1][j]]))

    for j in range(n[1]-1):
        for i in range(n[0]-1):
            centered_node_dict[i, j] = len(points)
            points.append(numpy.array([points_1d[0][i], points_1d[1][j]]) + half_dx)

    elements = []

    if periodicity is None:
        periodicity = (False, False)

    axes = ["x", "y"]
    mesh_periodicity = []
    periodic_tags = set()
    for i, axis in enumerate(axes):
        if periodicity[i]:
            minus_tag = "minus_"+axis
            plus_tag = "plus_"+axis
            mesh_periodicity.append((minus_tag, plus_tag))
            periodic_tags.add(minus_tag)
            periodic_tags.add(plus_tag)
        else:
            mesh_periodicity.append(None)

    fvi2fm = {}

    for i in range(n[0]-1):
        for j in range(n[1]-1):

            # c---d
            # |\ /|
            # | m |
            # |/ \|
            # a---b

            a = node_dict[i, j]
            b = node_dict[i+1, j]
            c = node_dict[i, j+1]
            d = node_dict[i+1, j+1]

            m = centered_node_dict[i, j]

            elements.append((a, b, m))
            elements.append((b, d, m))
            elements.append((d, c, m))
            elements.append((c, a, m))

            if i == 0:
                fvi2fm[frozenset((a, c))] = "minus_x"
            if i == n[0]-2:
                fvi2fm[frozenset((b, d))] = "plus_x"
            if j == 0:
                fvi2fm[frozenset((a, b))] = "minus_y"
            if j == n[1]-2:
                fvi2fm[frozenset((c, d))] = "plus_y"

    def wrapped_boundary_tagger(fvi, el, fn, all_v):
        btag = fvi2fm[frozenset(fvi)]
        if btag in periodic_tags:
            return [btag]
        else:
            return [btag] + boundary_tagger(fvi, el, fn, all_v)

    if post_refine_factor > 1:
        from meshpy.tools import uniform_refine_triangles
        points, elements, of2nf = uniform_refine_triangles(
                points, elements, post_refine_factor)
        old_fvi2fm = fvi2fm
        fvi2fm = {}

        for fvi, fm in old_fvi2fm.iteritems():
            for new_fvi in of2nf[fvi]:
                fvi2fm[frozenset(new_fvi)] = fm

    vertices = numpy.asarray(points, dtype=float, order="C")

    from hedge.mesh import make_conformal_mesh_ext
    from hedge.mesh.element import Triangle
    return make_conformal_mesh_ext(
            vertices,
            [Triangle(i, el_idx, vertices)
                for i, el_idx in enumerate(elements)],
            wrapped_boundary_tagger,
            periodicity=mesh_periodicity)
Пример #18
0
def make_squaremesh():
    def round_trip_connect(seq):
        result = []
        for i in range(len(seq)):
            result.append((i, (i + 1) % len(seq)))
        return result

    def needs_refinement(vertices, area):
        x = sum(numpy.array(v) for v in vertices) / 3

        max_area_volume = 0.7e-2 + 0.03 * (0.05 * x[1]**2 +
                                           0.3 * min(x[0] + 1, 0)**2)

        max_area_corners = 1e-3 + 0.001 * max(
            la.norm(x - corner)**4 for corner in obstacle_corners)

        return bool(area > 2.5 * min(max_area_volume, max_area_corners))

    from meshpy.geometry import make_box
    points, facets, _, _ = make_box((-0.5, -0.5), (0.5, 0.5))
    obstacle_corners = points[:]

    from meshpy.geometry import GeometryBuilder, Marker

    profile_marker = Marker.FIRST_USER_MARKER
    builder = GeometryBuilder()
    builder.add_geometry(points=points,
                         facets=facets,
                         facet_markers=profile_marker)

    points, facets, _, facet_markers = make_box((-16, -22), (25, 22))
    builder.add_geometry(points=points,
                         facets=facets,
                         facet_markers=facet_markers)

    from meshpy.triangle import MeshInfo, build
    mi = MeshInfo()
    builder.set(mi)
    mi.set_holes([(0, 0)])

    mesh = build(mi,
                 refinement_func=needs_refinement,
                 allow_boundary_steiner=True,
                 generate_faces=True)

    print "%d elements" % len(mesh.elements)

    from meshpy.triangle import write_gnuplot_mesh
    write_gnuplot_mesh("mesh.dat", mesh)

    fvi2fm = mesh.face_vertex_indices_to_face_marker

    face_marker_to_tag = {
        profile_marker: "noslip",
        Marker.MINUS_X: "inflow",
        Marker.PLUS_X: "outflow",
        Marker.MINUS_Y: "inflow",
        Marker.PLUS_Y: "inflow"
    }

    def bdry_tagger(fvi, el, fn, all_v):
        face_marker = fvi2fm[fvi]
        return [face_marker_to_tag[face_marker]]

    from hedge.mesh import make_conformal_mesh_ext
    vertices = numpy.asarray(mesh.points, dtype=float, order="C")
    from hedge.mesh.element import Triangle
    return make_conformal_mesh_ext(vertices, [
        Triangle(i, el_idx, vertices) for i, el_idx in enumerate(mesh.elements)
    ], bdry_tagger)