Пример #1
0
def make_rect_mesh_with_corner(a=(0,0), b=(1,1), max_area=None,
        boundary_tagger=(lambda fvi, el, fn, all_v: []),
        corner_fraction=(0.3, 0.3),
        refine_func=None):
    """Create an unstructured rectangular mesh with a reentrant
    corner at (-x, -y).

    :param a: the lower left hand point of the rectangle
    :param b: the upper right hand point of the rectangle
    :param max_area: maximum area of each triangle.
    :param refine_func: A refinement function as taken by :func:`meshpy.triangle.build`.
    :param corner_fraction: Tuple of fraction of the width taken up by
      the rentrant corner.
    """
    if max_area is not None:
        if refine_func is not None:
            raise ValueError, "cannot specify both refine_func and max_area"
        def refine_func(vertices, area):
            return area > max_area

    marker2tag = {
            1: "minus_x",
            2: "minus_y",
            3: "plus_x",
            4: "plus_y",
            4: "plus_y",
            5: "corner_plus_y",
            6: "corner_plus_x",
            }

    a = numpy.asarray(a)
    b = numpy.asarray(b)
    diag =  b-a
    w = diag.copy(); w[1] = 0
    h = diag.copy(); h[0] = 0

    points = [
            a+h*corner_fraction[1],
            a+h*corner_fraction[1]+w*corner_fraction[0],
            a+w*corner_fraction[0],
            a+w,
            a+w+h,
            a+h,
            ]
    facets = list(_round_trip_connect(0, 5))
    facet_markers = [5,6,2,3,4,1]

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

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

    from hedge.mesh import make_conformal_mesh
    return make_conformal_mesh(
            generated_mesh.points,
            generated_mesh.elements,
            boundary_tagger)
Пример #2
0
def make_single_element_mesh(a=-0.5, b=0.5,
        boundary_tagger=(lambda vertices, face_indices: [])):
    n = 2
    node_dict = {}
    points = []
    points_1d = numpy.linspace(a, b, n)
    for j in range(n):
        for i in range(n):
            node_dict[i, j] = len(points)
            points.append(numpy.array([points_1d[i], points_1d[j]]))

    elements = [(
                node_dict[1, 1],
                node_dict[0, 1],
                node_dict[1, 0],
                )]

    boundary_faces = [(3, 1), (1, 2), (2, 3)]

    boundary_tags = dict(
            (frozenset(seg),
                boundary_tagger(points, seg))
                for seg in boundary_faces)

    from hedge.mesh import make_conformal_mesh
    return make_conformal_mesh(
            points,
            elements,
            boundary_tags)
Пример #3
0
def make_rect_mesh_with_corner(a=(0, 0), b=(1, 1), max_area=None,
        boundary_tagger=(lambda fvi, el, fn, all_v: []),
        corner_fraction=(0.3, 0.3),
        refine_func=None):
    """Create an unstructured rectangular mesh with a reentrant
    corner at (-x, -y).

    :param a: the lower left hand point of the rectangle
    :param b: the upper right hand point of the rectangle
    :param max_area: maximum area of each triangle.
    :param refine_func: A refinement function as taken by
      :func:`meshpy.triangle.build`.
    :param corner_fraction: Tuple of fraction of the width taken up by
      the rentrant corner.
    """
    if max_area is not None:
        if refine_func is not None:
            raise ValueError("cannot specify both refine_func and max_area")

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

    a = numpy.asarray(a)
    b = numpy.asarray(b)
    diag = b-a
    w = diag.copy()
    w[1] = 0
    h = diag.copy()
    h[0] = 0

    points = [
            a+h*corner_fraction[1],
            a+h*corner_fraction[1]+w*corner_fraction[0],
            a+w*corner_fraction[0],
            a+w,
            a+w+h,
            a+h,
            ]
    facets = list(_round_trip_connect(0, 5))
    facet_markers = [5, 6, 2, 3, 4, 1]

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

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

    from hedge.mesh import make_conformal_mesh
    return make_conformal_mesh(
            generated_mesh.points,
            generated_mesh.elements,
            boundary_tagger)
    def make_mesh():
        array = numpy.array

        #
        #    1---8---2
        #    |7 /|\ 1|
        #    | / | \ |
        #    |/ 6|0 \|
        #    5---4---7
        #    |\ 5|3 /|
        #    | \ | / |
        #    |4 \|/ 2|
        #    0---6---3
        #
        points = [
            array([-0.5, -0.5]),
            array([-0.5, 0.5]),
            array([0.5, 0.5]),
            array([0.5, -0.5]),
            array([0.0, 0.0]),
            array([-0.5, 0.0]),
            array([0.0, -0.5]),
            array([0.5, 0.0]),
            array([0.0, 0.5])
        ]

        elements = [
            [8, 7, 4],
            [8, 7, 2],
            [6, 7, 3],
            [7, 4, 6],
            [5, 6, 0],
            [5, 6, 4],
            [5, 8, 4],
            [1, 5, 8],
        ]

        def boundary_tagger(vertices, el, face_nr, all_v):
            if dot(el.face_normals[face_nr], v) < 0:
                return ["inflow"]
            else:
                return ["outflow"]

        from hedge.mesh import make_conformal_mesh
        return make_conformal_mesh(points, elements, boundary_tagger)
Пример #5
0
    def make_mesh():
        array = numpy.array

        #
        #    1---8---2
        #    |7 /|\ 1|
        #    | / | \ |
        #    |/ 6|0 \|
        #    5---4---7
        #    |\ 5|3 /|
        #    | \ | / |
        #    |4 \|/ 2|
        #    0---6---3
        #
        points = [
                array([-0.5, -0.5]),
                array([-0.5, 0.5]),
                array([0.5, 0.5]),
                array([0.5, -0.5]),
                array([0.0, 0.0]),
                array([-0.5, 0.0]),
                array([0.0, -0.5]),
                array([0.5, 0.0]),
                array([0.0, 0.5])]

        elements = [
                [8, 7, 4],
                [8, 7, 2],
                [6, 7, 3],
                [7, 4, 6],
                [5, 6, 0],
                [5, 6, 4],
                [5, 8, 4],
                [1, 5, 8],
                ]

        def boundary_tagger(vertices, el, face_nr, all_v):
            if dot(el.face_normals[face_nr], v) < 0:
                return ["inflow"]
            else:
                return ["outflow"]

        from hedge.mesh import make_conformal_mesh
        return make_conformal_mesh(points, elements, boundary_tagger)
Пример #6
0
def make_mesh(a, b, pml_width=0.25, **kwargs):
    from meshpy.geometry import GeometryBuilder, make_box
    geob = GeometryBuilder()

    box_points, box_facets, _, box_markers = make_box(a, b)
    geob.add_geometry(box_points, box_facets)
    geob.wrap_in_box(pml_width)

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

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

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

    from hedge.mesh import make_conformal_mesh
    return make_conformal_mesh(
            built_mi.points,
            built_mi.elements, 
            boundary_tagger)
Пример #7
0
def make_regular_rect_mesh(a=(0, 0), b=(1, 1), n=(5, 5), periodicity=None,
        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 = {}
    points = []
    points_1d = [numpy.linspace(a_i, b_i, n_i)
            for a_i, b_i, n_i in zip(a, b, n)]

    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]]))

    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
            # |  |
            # 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]

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

            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)

    from hedge.mesh import make_conformal_mesh
    return make_conformal_mesh(points, elements, wrapped_boundary_tagger,
            periodicity=mesh_periodicity)
Пример #8
0
def make_boxmesh():
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import GeometryBuilder, Marker, make_box

    geob = GeometryBuilder()

    box_marker = Marker.FIRST_USER_MARKER
    extent_small = 0.1*numpy.ones(3, dtype=numpy.float64)

    geob.add_geometry(*make_box(-extent_small, extent_small))

    # make small "separator box" for region attribute

    geob.add_geometry(
            *make_box(
                -extent_small*4,
                numpy.array([4, 0.4, 0.4], dtype=numpy.float64)))

    geob.add_geometry(
            *make_box(
                numpy.array([-1, -1, -1], dtype=numpy.float64),
                numpy.array([5, 1, 1], dtype=numpy.float64)))

    mesh_info = MeshInfo()
    geob.set(mesh_info)
    mesh_info.set_holes([(0, 0, 0)])

    # region attributes
    mesh_info.regions.resize(1)
    mesh_info.regions[0] = (
            # point in region
            list(extent_small*2) + [
            # region number
            1,
            # max volume in region
            #0.0001
            0.005
            ])

    mesh = build(mesh_info, max_volume=0.02,
            volume_constraints=True, attributes=True)
    print "%d elements" % len(mesh.elements)
    #mesh.write_vtk("box-in-box.vtk")
    #print "done writing"

    fvi2fm = mesh.face_vertex_indices_to_face_marker

    face_marker_to_tag = {
            box_marker: "noslip",
            Marker.MINUS_X: "inflow",
            Marker.PLUS_X: "outflow",
            Marker.MINUS_Y: "inflow",
            Marker.PLUS_Y: "inflow",
            Marker.PLUS_Z: "inflow",
            Marker.MINUS_Z: "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
    return make_conformal_mesh(
            mesh.points, mesh.elements, bdry_tagger)
Пример #9
0
def make_wingmesh():
    import numpy
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import GeometryBuilder, Marker, \
            generate_extrusion, make_box

    geob = GeometryBuilder()

    profile_marker = Marker.FIRST_USER_MARKER

    wing_length = 2
    wing_subdiv = 5

    rz_points = [
            (0, -wing_length*1.05),
            (0.7, -wing_length*1.05),
            ] + [
                (r, x) for x, r in zip(
                    numpy.linspace(-wing_length, 0, wing_subdiv, endpoint=False),
                    numpy.linspace(0.8, 1, wing_subdiv, endpoint=False))
            ] + [(1,0)] + [
                (r, x) for x, r in zip(
                    numpy.linspace(wing_length, 0, wing_subdiv, endpoint=False),
                    numpy.linspace(0.8, 1, wing_subdiv, endpoint=False))
            ][::-1] + [
            (0.7, wing_length*1.05),
            (0, wing_length*1.05)
            ]

    from meshpy.naca import get_naca_points
    geob.add_geometry(*generate_extrusion(
        rz_points=rz_points,
        base_shape=get_naca_points("0012", number_of_points=20),
        ring_markers=(wing_subdiv*2+4)*[profile_marker]))

    def deform_wing(p):
        x, y, z = p
        return numpy.array([
            x + 0.8*abs(z/wing_length)** 1.2,
            y + 0.1*abs(z/wing_length)**2,
            z])

    geob.apply_transform(deform_wing)

    points, facets, facet_markers = make_box(
            numpy.array([-1.5,-1,-wing_length-1], dtype=numpy.float64),
            numpy.array([3,1,wing_length+1], dtype=numpy.float64))

    geob.add_geometry(points, facets, facet_markers=facet_markers)

    mesh_info = MeshInfo()
    geob.set(mesh_info)
    mesh_info.set_holes([(0.5,0,0)])

    mesh = build(mesh_info)
    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.PLUS_Z: "inflow",
            Marker.MINUS_Z: "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
    return make_conformal_mesh(mesh.points, mesh.elements, bdry_tagger)
Пример #10
0
def test_interior_fluxes_tet():
    """Check tetrahedron surface integrals computed using interior fluxes
    against their known values.
    """

    import meshpy.tet as tet
    from math import pi, sin, cos

    mesh_info = tet.MeshInfo()

    # construct a two-box extrusion of this base
    base = [(-pi, -pi, 0), (pi, -pi, 0), (pi, pi, 0), (-pi, pi, 0)]

    # first, the nodes
    mesh_info.set_points(base + [(x, y, z + pi)
                                 for x, y, z in base] + [(x, y, z + pi + 1)
                                                         for x, y, z in base])

    # next, the facets

    # vertex indices for a box missing the -z face
    box_without_minus_z = [
        [4, 5, 6, 7],
        [0, 4, 5, 1],
        [1, 5, 6, 2],
        [2, 6, 7, 3],
        [3, 7, 4, 0],
    ]

    def add_to_all_vertex_indices(facets, increment):
        return [[pt + increment for pt in facet] for facet in facets]

    mesh_info.set_facets(
        [[0, 1, 2, 3]]  # base
        + box_without_minus_z  # first box
        + add_to_all_vertex_indices(box_without_minus_z, 4)  # second box
    )

    # set the volume properties -- this is where the tet size constraints are
    mesh_info.regions.resize(2)
    mesh_info.regions[0] = [
        0,
        0,
        pi / 2,  # point in volume -> first box
        0,  # region tag (user-defined number)
        0.5,  # max tet volume in region
    ]
    mesh_info.regions[1] = [
        0,
        0,
        pi + 0.5,  # point in volume -> second box
        1,  # region tag (user-defined number,  arbitrary)
        0.1,  # max tet volume in region
    ]

    generated_mesh = tet.build(mesh_info,
                               attributes=True,
                               volume_constraints=True)

    from hedge.mesh import make_conformal_mesh
    mesh = make_conformal_mesh(generated_mesh.points, generated_mesh.elements)

    from hedge.discretization.local import TetrahedronDiscretization
    from hedge.discretization import ones_on_volume
    discr = discr_class(mesh,
                        TetrahedronDiscretization(4),
                        debug=discr_class.noninteractive_debug_flags())

    def f_u(x, el):
        if generated_mesh.element_attributes[el.id] == 1:
            return cos(x[0] - x[1] + x[2])
        else:
            return 0

    def f_l(x, el):
        if generated_mesh.element_attributes[el.id] == 0:
            return sin(x[0] - x[1] + x[2])
        else:
            return 0

    u_l = discr.interpolate_volume_function(f_l)
    u_u = discr.interpolate_volume_function(f_u)
    u = u_l + u_u

    # visualize the produced field
    #from hedge.visualization import SiloVisualizer
    #vis = SiloVisualizer(discr)
    #visf = vis.make_file("sandwich")
    #vis.add_data(visf,
    #[("u_l", u_l), ("u_u", u_u)],
    #expressions=[("u", "u_l+u_u")])

    # make sure the surface integral of the difference
    # between top and bottom is zero
    from hedge.flux import make_normal, FluxScalarPlaceholder
    from hedge.optemplate import Field, get_flux_operator

    fluxu = FluxScalarPlaceholder()
    res = discr.compile(
        get_flux_operator(
            (fluxu.int - fluxu.ext) * make_normal(discr.dimensions)[1]) *
        Field("u"))(u=u)

    ones = ones_on_volume(discr)
    assert abs(numpy.dot(res, ones)) < 5e-14
Пример #11
0
def partition_mesh(mesh, partition, part_bdry_tag_factory):
    """*partition* is a mapping that maps element id to
    integers that represent different pieces of the mesh.

    For historical reasons, the values in partition are called
    'parts'.
    """

    # Find parts to which we need to distribute.
    all_parts = list(set(
        partition[el.id] for el in mesh.elements))

    # Prepare a mapping of elements to tags to speed up
    # copy_el_tagger, below.
    el2tags = {}
    for tag, elements in mesh.tag_to_elements.iteritems():
        if tag == hedge.mesh.TAG_ALL:
            continue
        for el in elements:
            el2tags.setdefault(el, []).append(tag)

    # prepare a mapping of (el, face_nr) to boundary_tags
    # to speed up partition_bdry_tagger, below
    elface2tags = {}
    for tag, elfaces in mesh.tag_to_boundary.iteritems():
        if tag == hedge.mesh.TAG_ALL:
            continue
        for el, fn in elfaces:
            elface2tags.setdefault((el, fn), []).append(tag)

    # prepare a mapping from (el, face_nr) to the part
    # at the other end of the interface, if different from
    # current. concurrently, prepare a mapping
    #  part -> set([parts that border me])
    elface2part = {}
    neighboring_parts = {}

    for elface1, elface2 in mesh.interfaces:
        e1, f1 = elface1
        e2, f2 = elface2
        r1 = partition[e1.id]
        r2 = partition[e2.id]

        if r1 != r2:
            neighboring_parts.setdefault(r1, set()).add(r2)
            neighboring_parts.setdefault(r2, set()).add(r1)

            elface2part[elface1] = r2
            elface2part[elface2] = r1

    # prepare a new mesh for each part and send it
    from hedge.mesh import TAG_NO_BOUNDARY

    for part in all_parts:
        part_global_elements = [el
                for el in mesh.elements
                if partition[el.id] == part]

        # pick out this part's vertices
        from pytools import flatten
        part_global_vertex_indices = set(flatten(
                el.vertex_indices for el in part_global_elements))

        part_local_vertices = [mesh.points[vi]
                for vi in part_global_vertex_indices]

        # find global-to-local maps
        part_global2local_vertex_indices = dict(
                (gvi, lvi) for lvi, gvi in
                enumerate(part_global_vertex_indices))

        part_global2local_elements = dict(
                (el.id, i) for i, el in
                enumerate(part_global_elements))

        # find elements in local numbering
        part_local_elements = [
                [part_global2local_vertex_indices[vi]
                    for vi in el.vertex_indices]
                for el in part_global_elements]

        # make new local Mesh object, including
        # boundary and element tagging
        def partition_bdry_tagger(fvi, local_el, fn, all_vertices):
            el = part_global_elements[local_el.id]

            result = elface2tags.get((el, fn), [])
            try:
                opp_part = elface2part[el, fn]
                result.append(part_bdry_tag_factory(opp_part))

                # keeps this part of the boundary from falling
                # under TAG_ALL.
                result.append(TAG_NO_BOUNDARY)

            except KeyError:
                pass

            return result

        def copy_el_tagger(local_el, all_vertices):
            return el2tags.get(part_global_elements[local_el.id], [])

        def is_partbdry_face((local_el, face_nr)):
            return (part_global_elements[local_el.id], face_nr) in elface2part

        from hedge.mesh import make_conformal_mesh
        part_mesh = make_conformal_mesh(
                part_local_vertices,
                part_local_elements,
                partition_bdry_tagger,
                copy_el_tagger,
                mesh.periodicity,
                is_partbdry_face)

        # assemble per-part data

        my_nb_parts = neighboring_parts.get(part, [])
        yield PartitionData(
                part,
                part_mesh,
                part_global2local_elements,
                part_global2local_vertex_indices,
                my_nb_parts,
                mesh.periodic_opposite_faces,
                part_boundary_tags=dict(
                    (nb_part, part_bdry_tag_factory(nb_part))
                    for nb_part in my_nb_parts),
                tag_to_elements = part_mesh.tag_to_elements
                )
Пример #12
0
def partition_mesh(mesh, partition, part_bdry_tag_factory):
    """*partition* is a mapping that maps element id to
    integers that represent different pieces of the mesh.

    For historical reasons, the values in partition are called
    'parts'.
    """

    # Find parts to which we need to distribute.
    all_parts = list(set(partition[el.id] for el in mesh.elements))

    # Prepare a mapping of elements to tags to speed up
    # copy_el_tagger, below.
    el2tags = {}
    for tag, elements in mesh.tag_to_elements.iteritems():
        if tag == hedge.mesh.TAG_ALL:
            continue
        for el in elements:
            el2tags.setdefault(el, []).append(tag)

    # prepare a mapping of (el, face_nr) to boundary_tags
    # to speed up partition_bdry_tagger, below
    elface2tags = {}
    for tag, elfaces in mesh.tag_to_boundary.iteritems():
        if tag == hedge.mesh.TAG_ALL:
            continue
        for el, fn in elfaces:
            elface2tags.setdefault((el, fn), []).append(tag)

    # prepare a mapping from (el, face_nr) to the part
    # at the other end of the interface, if different from
    # current. concurrently, prepare a mapping
    #  part -> set([parts that border me])
    elface2part = {}
    neighboring_parts = {}

    for elface1, elface2 in mesh.interfaces:
        e1, f1 = elface1
        e2, f2 = elface2
        r1 = partition[e1.id]
        r2 = partition[e2.id]

        if r1 != r2:
            neighboring_parts.setdefault(r1, set()).add(r2)
            neighboring_parts.setdefault(r2, set()).add(r1)

            elface2part[elface1] = r2
            elface2part[elface2] = r1

    # prepare a new mesh for each part and send it
    from hedge.mesh import TAG_NO_BOUNDARY

    for part in all_parts:
        part_global_elements = [
            el for el in mesh.elements if partition[el.id] == part
        ]

        # pick out this part's vertices
        from pytools import flatten
        part_global_vertex_indices = set(
            flatten(el.vertex_indices for el in part_global_elements))

        part_local_vertices = [
            mesh.points[vi] for vi in part_global_vertex_indices
        ]

        # find global-to-local maps
        part_global2local_vertex_indices = dict(
            (gvi, lvi) for lvi, gvi in enumerate(part_global_vertex_indices))

        part_global2local_elements = dict(
            (el.id, i) for i, el in enumerate(part_global_elements))

        # find elements in local numbering
        part_local_elements = [[
            part_global2local_vertex_indices[vi] for vi in el.vertex_indices
        ] for el in part_global_elements]

        # make new local Mesh object, including
        # boundary and element tagging
        def partition_bdry_tagger(fvi, local_el, fn, all_vertices):
            el = part_global_elements[local_el.id]

            result = elface2tags.get((el, fn), [])
            try:
                opp_part = elface2part[el, fn]
                result.append(part_bdry_tag_factory(opp_part))

                # keeps this part of the boundary from falling
                # under TAG_ALL.
                result.append(TAG_NO_BOUNDARY)

            except KeyError:
                pass

            return result

        def copy_el_tagger(local_el, all_vertices):
            return el2tags.get(part_global_elements[local_el.id], [])

        def is_partbdry_face((local_el, face_nr)):
            return (part_global_elements[local_el.id], face_nr) in elface2part

        from hedge.mesh import make_conformal_mesh
        part_mesh = make_conformal_mesh(part_local_vertices,
                                        part_local_elements,
                                        partition_bdry_tagger, copy_el_tagger,
                                        mesh.periodicity, is_partbdry_face)

        # assemble per-part data

        my_nb_parts = neighboring_parts.get(part, [])
        yield PartitionData(part,
                            part_mesh,
                            part_global2local_elements,
                            part_global2local_vertex_indices,
                            my_nb_parts,
                            mesh.periodic_opposite_faces,
                            part_boundary_tags=dict(
                                (nb_part, part_bdry_tag_factory(nb_part))
                                for nb_part in my_nb_parts),
                            tag_to_elements=part_mesh.tag_to_elements)
Пример #13
0
def test_interior_fluxes_tet():
    """Check tetrahedron surface integrals computed using interior fluxes
    against their known values.
    """

    import meshpy.tet as tet
    from math import pi, sin, cos

    mesh_info = tet.MeshInfo()

    # construct a two-box extrusion of this base
    base = [(-pi, -pi, 0), (pi, -pi, 0), (pi, pi, 0), (-pi, pi, 0)]

    # first, the nodes
    mesh_info.set_points(base + [(x, y, z + pi) for x, y, z in base] + [(x, y, z + pi + 1) for x, y, z in base])

    # next, the facets

    # vertex indices for a box missing the -z face
    box_without_minus_z = [[4, 5, 6, 7], [0, 4, 5, 1], [1, 5, 6, 2], [2, 6, 7, 3], [3, 7, 4, 0]]

    def add_to_all_vertex_indices(facets, increment):
        return [[pt + increment for pt in facet] for facet in facets]

    mesh_info.set_facets(
        [[0, 1, 2, 3]]  # base
        + box_without_minus_z  # first box
        + add_to_all_vertex_indices(box_without_minus_z, 4)  # second box
    )

    # set the volume properties -- this is where the tet size constraints are
    mesh_info.regions.resize(2)
    mesh_info.regions[0] = [
        0,
        0,
        pi / 2,  # point in volume -> first box
        0,  # region tag (user-defined number)
        0.5,  # max tet volume in region
    ]
    mesh_info.regions[1] = [
        0,
        0,
        pi + 0.5,  # point in volume -> second box
        1,  # region tag (user-defined number, arbitrary)
        0.1,  # max tet volume in region
    ]

    generated_mesh = tet.build(mesh_info, attributes=True, volume_constraints=True)

    from hedge.mesh import make_conformal_mesh

    mesh = make_conformal_mesh(generated_mesh.points, generated_mesh.elements)

    from hedge.discretization.local import TetrahedronDiscretization
    from hedge.discretization import ones_on_volume

    discr = discr_class(mesh, TetrahedronDiscretization(4), debug=discr_class.noninteractive_debug_flags())

    def f_u(x, el):
        if generated_mesh.element_attributes[el.id] == 1:
            return cos(x[0] - x[1] + x[2])
        else:
            return 0

    def f_l(x, el):
        if generated_mesh.element_attributes[el.id] == 0:
            return sin(x[0] - x[1] + x[2])
        else:
            return 0

    u_l = discr.interpolate_volume_function(f_l)
    u_u = discr.interpolate_volume_function(f_u)
    u = u_l + u_u

    # visualize the produced field
    # from hedge.visualization import SiloVisualizer
    # vis = SiloVisualizer(discr)
    # visf = vis.make_file("sandwich")
    # vis.add_data(visf,
    # [("u_l", u_l), ("u_u", u_u)],
    # expressions=[("u", "u_l+u_u")])

    # make sure the surface integral of the difference
    # between top and bottom is zero
    from hedge.flux import make_normal, FluxScalarPlaceholder
    from hedge.optemplate import Field, get_flux_operator

    fluxu = FluxScalarPlaceholder()
    res = discr.compile(get_flux_operator((fluxu.int - fluxu.ext) * make_normal(discr.dimensions)[1]) * Field("u"))(u=u)

    from hedge.discretization import ones_on_volume

    ones = ones_on_volume(discr)
    assert abs(numpy.dot(res, ones)) < 5e-14
Пример #14
0
def test_interior_fluxes_tri():
    """Check triangle surface integrals computed using interior fluxes
    against their known values.
    """

    from math import pi, sin, cos

    def round_trip_connect(start, end):
        for i in range(start, end):
            yield i, i + 1
        yield end, start

    a = -pi
    b = pi
    points = [(a, 0), (b, 0), (a, -1), (b, -1), (a, 1), (b, 1)]

    import meshpy.triangle as triangle

    mesh_info = triangle.MeshInfo()
    mesh_info.set_points(points)
    mesh_info.set_facets([(0, 1), (1, 3), (3, 2), (2, 0), (0, 4), (4, 5), (1, 5)])

    mesh_info.regions.resize(2)
    mesh_info.regions[0] = [0, -0.5, 1, 0.1]  # coordinate  # lower element tag  # max area
    mesh_info.regions[1] = [0, 0.5, 2, 0.01]  # coordinate  # upper element tag  # max area

    generated_mesh = triangle.build(mesh_info, attributes=True, volume_constraints=True)
    # triangle.write_gnuplot_mesh("mesh.dat", generated_mesh)

    def element_tagger(el):
        if generated_mesh.element_attributes[el.id] == 1:
            return ["upper"]
        else:
            return ["lower"]

    from hedge.mesh import make_conformal_mesh

    mesh = make_conformal_mesh(generated_mesh.points, generated_mesh.elements)

    from hedge.discretization.local import TriangleDiscretization
    from hedge.discretization import ones_on_volume

    discr = discr_class(mesh, TriangleDiscretization(4), debug=discr_class.noninteractive_debug_flags())

    def f_u(x, el):
        if generated_mesh.element_attributes[el.id] == 1:
            return cos(x[0] - x[1])
        else:
            return 0

    def f_l(x, el):
        if generated_mesh.element_attributes[el.id] == 0:
            return sin(x[0] - x[1])
        else:
            return 0

    u_l = discr.interpolate_volume_function(f_l)
    u_u = discr.interpolate_volume_function(f_u)
    u = u_u + u_u

    # discr.visualize_vtk("dual.vtk", [("u", u)])

    from hedge.flux import make_normal, FluxScalarPlaceholder
    from hedge.optemplate import Field, get_flux_operator

    fluxu = FluxScalarPlaceholder()
    res = discr.compile(get_flux_operator((fluxu.int - fluxu.ext) * make_normal(discr.dimensions)[1]) * Field("u"))(u=u)

    from hedge.discretization import ones_on_volume

    ones = ones_on_volume(discr)
    err = abs(numpy.dot(res, ones))
    # print err
    assert err < 5e-14
Пример #15
0
def make_boxmesh():
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import GeometryBuilder, Marker, make_box

    geob = GeometryBuilder()

    box_marker = Marker.FIRST_USER_MARKER
    extent_small = 0.1 * numpy.ones(3, dtype=numpy.float64)

    geob.add_geometry(*make_box(-extent_small, extent_small))

    # make small "separator box" for region attribute

    geob.add_geometry(
        *make_box(-extent_small *
                  4, numpy.array([4, 0.4, 0.4], dtype=numpy.float64)))

    geob.add_geometry(*make_box(numpy.array([-1, -1, -1], dtype=numpy.float64),
                                numpy.array([5, 1, 1], dtype=numpy.float64)))

    mesh_info = MeshInfo()
    geob.set(mesh_info)
    mesh_info.set_holes([(0, 0, 0)])

    # region attributes
    mesh_info.regions.resize(1)
    mesh_info.regions[0] = (
        # point in region
        list(extent_small * 2) + [
            # region number
            1,
            # max volume in region
            #0.0001
            0.005
        ])

    mesh = build(mesh_info,
                 max_volume=0.02,
                 volume_constraints=True,
                 attributes=True)
    print "%d elements" % len(mesh.elements)
    #mesh.write_vtk("box-in-box.vtk")
    #print "done writing"

    fvi2fm = mesh.face_vertex_indices_to_face_marker

    face_marker_to_tag = {
        box_marker: "noslip",
        Marker.MINUS_X: "inflow",
        Marker.PLUS_X: "outflow",
        Marker.MINUS_Y: "inflow",
        Marker.PLUS_Y: "inflow",
        Marker.PLUS_Z: "inflow",
        Marker.MINUS_Z: "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
    return make_conformal_mesh(mesh.points, mesh.elements, bdry_tagger)
Пример #16
0
def test_interior_fluxes_tri():
    """Check triangle surface integrals computed using interior fluxes
    against their known values.
    """

    from math import pi, sin, cos

    def round_trip_connect(start, end):
        for i in range(start, end):
            yield i, i + 1
        yield end, start

    a = -pi
    b = pi
    points = [(a, 0), (b, 0), (a, -1), (b, -1), (a, 1), (b, 1)]

    import meshpy.triangle as triangle

    mesh_info = triangle.MeshInfo()
    mesh_info.set_points(points)
    mesh_info.set_facets([(0, 1), (1, 3), (3, 2), (2, 0), (0, 4), (4, 5),
                          (1, 5)])

    mesh_info.regions.resize(2)
    mesh_info.regions[0] = [
        0,
        -0.5,  # coordinate
        1,  # lower element tag
        0.1,  # max area
    ]
    mesh_info.regions[1] = [
        0,
        0.5,  # coordinate
        2,  # upper element tag
        0.01,  # max area
    ]

    generated_mesh = triangle.build(mesh_info,
                                    attributes=True,
                                    volume_constraints=True)

    #triangle.write_gnuplot_mesh("mesh.dat", generated_mesh)

    def element_tagger(el):
        if generated_mesh.element_attributes[el.id] == 1:
            return ["upper"]
        else:
            return ["lower"]

    from hedge.mesh import make_conformal_mesh
    mesh = make_conformal_mesh(generated_mesh.points, generated_mesh.elements)

    from hedge.discretization.local import TriangleDiscretization
    from hedge.discretization import ones_on_volume
    discr = discr_class(mesh,
                        TriangleDiscretization(4),
                        debug=discr_class.noninteractive_debug_flags())

    def f_u(x, el):
        if generated_mesh.element_attributes[el.id] == 1:
            return cos(x[0] - x[1])
        else:
            return 0

    def f_l(x, el):
        if generated_mesh.element_attributes[el.id] == 0:
            return sin(x[0] - x[1])
        else:
            return 0

    # u_l = discr.interpolate_volume_function(f_l)
    u_u = discr.interpolate_volume_function(f_u)
    u = u_u + u_u

    #discr.visualize_vtk("dual.vtk", [("u", u)])

    from hedge.flux import make_normal, FluxScalarPlaceholder
    from hedge.optemplate import Field, get_flux_operator
    fluxu = FluxScalarPlaceholder()
    res = discr.compile(
        get_flux_operator(
            (fluxu.int - fluxu.ext) * make_normal(discr.dimensions)[1]) *
        Field("u"))(u=u)

    ones = ones_on_volume(discr)
    err = abs(numpy.dot(res, ones))
    #print err
    assert err < 5e-14
Пример #17
0
def make_wingmesh():
    import numpy
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import GeometryBuilder, Marker, \
            generate_extrusion, make_box

    geob = GeometryBuilder()

    profile_marker = Marker.FIRST_USER_MARKER

    wing_length = 2
    wing_subdiv = 5

    rz_points = [
        (0, -wing_length * 1.05),
        (0.7, -wing_length * 1.05),
    ] + [(r, x) for x, r in zip(
        numpy.linspace(-wing_length, 0, wing_subdiv, endpoint=False),
        numpy.linspace(0.8, 1, wing_subdiv, endpoint=False))] + [(1, 0)] + [
            (r, x) for x, r in zip(
                numpy.linspace(wing_length, 0, wing_subdiv, endpoint=False),
                numpy.linspace(0.8, 1, wing_subdiv, endpoint=False))
        ][::-1] + [(0.7, wing_length * 1.05), (0, wing_length * 1.05)]

    from meshpy.naca import get_naca_points
    geob.add_geometry(*generate_extrusion(
        rz_points=rz_points,
        base_shape=get_naca_points("0012", number_of_points=20),
        ring_markers=(wing_subdiv * 2 + 4) * [profile_marker]))

    def deform_wing(p):
        x, y, z = p
        return numpy.array([
            x + 0.8 * abs(z / wing_length)**1.2,
            y + 0.1 * abs(z / wing_length)**2, z
        ])

    geob.apply_transform(deform_wing)

    points, facets, facet_markers = make_box(
        numpy.array([-1.5, -1, -wing_length - 1], dtype=numpy.float64),
        numpy.array([3, 1, wing_length + 1], dtype=numpy.float64))

    geob.add_geometry(points, facets, facet_markers=facet_markers)

    mesh_info = MeshInfo()
    geob.set(mesh_info)
    mesh_info.set_holes([(0.5, 0, 0)])

    mesh = build(mesh_info)
    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.PLUS_Z: "inflow",
        Marker.MINUS_Z: "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
    return make_conformal_mesh(mesh.points, mesh.elements, bdry_tagger)