Example #1
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)
Example #2
0
def main():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import \
            generate_surface_of_revolution, EXT_OPEN, \
            GeometryBuilder

    r = 3

    points = 10
    dphi = pi/points

    def truncate(r):
        if abs(r) < 1e-10:
            return 0
        else:
            return r

    rz = [(truncate(r*sin(i*dphi)), r*cos(i*dphi)) for i in range(points+1)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(rz,
            closure=EXT_OPEN, radial_subdiv=10))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh = build(mesh_info)
    mesh.write_vtk("ball.vtk")
Example #3
0
 def __init__(self, figsize=6):
     # Material Properties
     self.materials = {}
     # Mesh Properties
     self.builder = GeometryBuilder()
     self.reinforcement = []
     self.outer_facets = []
     self.mesh_areas = {}
     self.mesh_centroids = {}
     self.mesh = None
     # Data structure to assign material ids after mesh generation
     self.ele_mat_primitive = []
     self.ele_mat = {}
     # Load step Data
     self.load_angle = 0
     self.phi_list = []
     self.M_list = []
     # States of all elements at each load step from analysis
     self.state_id = 0
     self.states = {}
     self.state_y_loc = {}
     self.analysis_model = FiberModel()
     # Failure check for end of analysis (conf crush/ bar fracture)
     self.fail = False
     # Plot settings
     self.figsize = figsize
Example #4
0
def main():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import generate_surface_of_revolution,\
            EXT_CLOSED_IN_RZ, GeometryBuilder

    big_r = 3
    little_r = 2.9

    points = 50
    dphi = 2*pi/points

    rz = [(big_r+little_r*cos(i*dphi), little_r*sin(i*dphi))
            for i in range(points)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(rz,
            closure=EXT_CLOSED_IN_RZ, radial_subdiv=20))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh_info.save_nodes("torus")
    mesh_info.save_poly("torus")
    mesh = build(mesh_info)
    mesh.write_vtk("torus.vtk")
    mesh.save_elements("torus_mesh")
    mesh.save_nodes("torus_mesh")

    mesh.write_neu(file("torus.neu", "w"),
            {1: ("pec", 0)})
Example #5
0
def main():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import \
            generate_surface_of_revolution, EXT_OPEN, \
            GeometryBuilder

    r = 1
    l = 1

    rz = [(0,0), (r,0), (r,l), (0,l)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(rz,
            radial_subdiv=20, ring_markers=[1,2,3]))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh = build(mesh_info, max_volume=0.01)
    mesh.write_vtk("cylinder.vtk")
    mesh.write_neu(open("cylinder.neu", "w"), {
        1: ("minus_z", 1),
        2: ("outer", 2),
        3: ("plus_z", 3),
        })
Example #6
0
def main():
    import numpy as np
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import \
            GeometryBuilder, generate_surface_of_revolution, EXT_CLOSED_IN_RZ

    big_r = 3
    little_r = 1.5

    points = 50
    dphi = 2*pi/points

    rz = np.array([[big_r+little_r*cos(i*dphi), little_r*sin(i*dphi)]
            for i in range(points)])

    geo = GeometryBuilder()
    geo.add_geometry(
            *generate_surface_of_revolution(rz,
                closure=EXT_CLOSED_IN_RZ, radial_subdiv=20))

    mesh_info = MeshInfo()
    geo.set(mesh_info)

    mesh = build(mesh_info)

    def tet_face_vertices(vertices):
        return [(vertices[0], vertices[1], vertices[2]),
                (vertices[0], vertices[1], vertices[3]),
                (vertices[0], vertices[2], vertices[3]),
                (vertices[1], vertices[2], vertices[3]),
                ]

    face_map = {}
    for el_id, el in enumerate(mesh.elements):
        for fid, face_vertices in enumerate(tet_face_vertices(el)):
            face_map.setdefault(frozenset(face_vertices), []).append((el_id, fid))

    adjacency = {}
    for face_vertices, els_faces in face_map.items():
        if len(els_faces) == 2:
            (e1, f1), (e2, f2) = els_faces
            adjacency.setdefault(e1, []).append(e2)
            adjacency.setdefault(e2, []).append(e1)

    from pymetis import part_graph

    cuts, part_vert = part_graph(17, adjacency)

    try:
        import pyvtk
    except ImportError:
        print("Test succeeded, but could not import pyvtk to visualize result")
    else:
        vtkelements = pyvtk.VtkData(
            pyvtk.UnstructuredGrid(mesh.points, tetra=mesh.elements),
            "Mesh",
            pyvtk.CellData(pyvtk.Scalars(part_vert, name="partition")))
        vtkelements.tofile('split.vtk')
Example #7
0
def test_tet_mesh(visualize=False):
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import GeometryBuilder, generate_surface_of_revolution, EXT_CLOSED_IN_RZ

    pytest.importorskip("meshpy")

    big_r = 3
    little_r = 1.5

    points = 50
    dphi = 2*pi/points

    rz = np.array([[big_r+little_r*cos(i*dphi), little_r*sin(i*dphi)]
            for i in range(points)])

    geo = GeometryBuilder()
    geo.add_geometry(
            *generate_surface_of_revolution(rz,
                closure=EXT_CLOSED_IN_RZ, radial_subdiv=20))

    mesh_info = MeshInfo()
    geo.set(mesh_info)

    mesh = build(mesh_info)

    def tet_face_vertices(vertices):
        return [(vertices[0], vertices[1], vertices[2]),
                (vertices[0], vertices[1], vertices[3]),
                (vertices[0], vertices[2], vertices[3]),
                (vertices[1], vertices[2], vertices[3]),
                ]

    face_map = {}
    for el_id, el in enumerate(mesh.elements):
        for fid, face_vertices in enumerate(tet_face_vertices(el)):
            face_map.setdefault(frozenset(face_vertices), []).append((el_id, fid))

    adjacency = {}
    for face_vertices, els_faces in face_map.items():
        if len(els_faces) == 2:
            (e1, f1), (e2, f2) = els_faces
            adjacency.setdefault(e1, []).append(e2)
            adjacency.setdefault(e2, []).append(e1)

    import ipdb; ipdb.set_trace()
    cuts, part_vert = pymetis.part_graph(17, adjacency)

    if visualize:
        import pyvtk

        vtkelements = pyvtk.VtkData(
            pyvtk.UnstructuredGrid(mesh.points, tetra=mesh.elements),
            "Mesh",
            pyvtk.CellData(pyvtk.Scalars(part_vert, name="partition")))
        vtkelements.tofile('split.vtk')
Example #8
0
def make_mesh(max_volume):
    def round_trip_connect(seq):
        result = []
        for i in range(len(seq)):
            result.append((i, (i+1)%len(seq)))
        return result

    shapes = read_shape()

    #from matplotlib.pyplot import plot,show
    #plot(shapes[0][:,0], shapes[0][:,1])
    #show()

    from meshpy.geometry import GeometryBuilder, Marker
    builder = GeometryBuilder()

    for shape in shapes:
        from meshpy.geometry import make_box
        points = shape
        facets = round_trip_connect(range(len(points)))
        builder.add_geometry(points=points, facets=facets,
                facet_markers=Marker.FIRST_USER_MARKER)

    points, facets, facet_markers = make_box((-200, -600), (400, -300))
    builder.add_geometry(points=points, facets=facets,
            facet_markers=facet_markers)

    def transform(pt):
        x, y = pt
        return -0.01*x, -0.01*y

    builder.apply_transform(transform)

    from meshpy.triangle import MeshInfo, build
    mi = MeshInfo()
    builder.set(mi)
    holes = []
    for shape, sign, frac in zip(shapes, [1, 1, -1, 1, 1, 1], [0.5, 0, 0, 0, 0, 0]):
        avg = np.average(shape, axis=0)
        start_idx = int(frac*shape.shape[0])
        start = shape[start_idx]
        holes.append(transform(start + sign*0.01*(avg-start)))

    mi.set_holes(holes)

    mesh = build(mi,
            allow_boundary_steiner=True,
            generate_faces=True,
            max_volume=max_volume)

    return mesh
Example #9
0
 def add_reinforcement(self, shape, mat_id, **kwargs):
     """Add reinforcement in a circle (for now), confine concrete inside if needed"""
     if shape == 'circle':
         if 'conf_id' in kwargs:
             reinforcement_builder = GeometryBuilder()
             reinforcement_builder.add_geometry(
                 *make_circle(kwargs['D'] /
                              2, kwargs['c'], kwargs['count']))
             r = ReinforcementProperties(reinforcement_builder.points,
                                         kwargs['bar'], mat_id)
             self.reinforcement.append(r)
             # Add points for confinement into mesh
             self.builder.add_geometry(*make_circle(kwargs['D'] /
                                                    2, kwargs['c']))
             self.ele_mat_primitive.append(
                 (kwargs['D'] / 2, kwargs['c'], kwargs['conf_id']))
         else:
             reinforcement_builder = GeometryBuilder()
             reinforcement_builder.add_geometry(
                 *make_circle(kwargs['D'] /
                              2, kwargs['c'], kwargs['count']))
             r = ReinforcementProperties(reinforcement_builder.points,
                                         kwargs['bar'], mat_id)
             self.reinforcement.append(r)
     else:
         # Rectangular reinforcement
         # not implemented for now
         print("I can only currently add type='circle' reinforcement")
         exit()
Example #10
0
def main():
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import generate_surface_of_revolution, GeometryBuilder

    simple_rz = [(0, 0), (1, 1), (1, 2), (0, 3)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(simple_rz))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    # mesh_info.save_nodes("test")
    # mesh_info.save_poly("test")
    # mesh_info.load_poly("test")
    mesh = build(mesh_info)
    mesh.write_vtk("my_mesh.vtk")
Example #11
0
def ball(h):
    from meshpy.geometry import (
        EXT_OPEN,
        GeometryBuilder,
        generate_surface_of_revolution,
    )
    from meshpy.tet import MeshInfo, build

    r = 3

    polar_subdivision = int(math.pi / h)
    dphi = math.pi / polar_subdivision

    def truncate(val):
        return 0 if abs(val) < 1e-10 else val

    rz = [
        [truncate(r * math.sin(i * dphi)), r * math.cos(i * dphi)]
        for i in range(polar_subdivision + 1)
    ]

    geob = GeometryBuilder()
    radial_subdivision = int(2 * math.pi / h)
    geob.add_geometry(
        *generate_surface_of_revolution(
            rz, closure=EXT_OPEN, radial_subdiv=radial_subdivision
        )
    )

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh = build(mesh_info)
    return numpy.array(mesh.points), numpy.array(mesh.elements)
Example #12
0
def main():
    import numpy
    from math import pi, cos, sin
    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)
    points, facets, _, _ = \
            make_box(-extent_small, extent_small)

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

    # make small "separator box" for region attribute
    geob.wrap_in_box(0.3)

    points, facets, _, facet_markers = \
            make_box(numpy.array([-1,-1,-1]), numpy.array([1,1,5]))

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

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

    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")
Example #13
0
def main():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import (
        generate_surface_of_revolution,
        EXT_CLOSED_IN_RZ,
        GeometryBuilder,
    )

    big_r = 3
    little_r = 2.9

    points = 50
    dphi = 2 * pi / points

    rz = [(big_r + little_r * cos(i * dphi), little_r * sin(i * dphi))
          for i in range(points)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(
        rz, closure=EXT_CLOSED_IN_RZ, radial_subdiv=20))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh_info.save_nodes("torus")
    mesh_info.save_poly("torus")
    mesh = build(mesh_info)
    mesh.write_vtk("torus.vtk")
    mesh.save_elements("torus_mesh")
    mesh.save_nodes("torus_mesh")

    mesh.write_neu(open("torus.neu", "w"), {1: ("pec", 0)})
Example #14
0
def main():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import \
            generate_surface_of_revolution, EXT_OPEN, \
            GeometryBuilder

    r = 1
    l = 1

    rz = [(0, 0), (r, 0), (r, l), (0, l)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(
        rz, radial_subdiv=20, ring_markers=[1, 2, 3]))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh = build(mesh_info, max_volume=0.01)
    mesh.write_vtk("cylinder.vtk")
    mesh.write_neu(file("cylinder.neu", "w"), {
        1: ("minus_z", 1),
        2: ("outer", 2),
        3: ("plus_z", 3),
    })
Example #15
0
def create_mesh(big_r=1.0, small_r=0.5, num_points=10):
    dphi = 2 * np.pi / num_points

    # Compute the volume of a canonical tetrahedron
    # with edgelength radius2*dphi.
    a = small_r * dphi
    canonical_tet_volume = np.sqrt(2.0) / 12 * a ** 3

    radial_subdiv = int(2 * np.pi * big_r / a)

    rz = [
        (big_r + small_r * np.cos(i * dphi), 0.5 * small_r * np.sin(i * dphi))
        for i in range(num_points)
    ]

    geob = GeometryBuilder()
    geob.add_geometry(
        *generate_surface_of_revolution(
            rz, closure=EXT_CLOSED_IN_RZ, radial_subdiv=radial_subdiv
        )
    )
    mesh_info = MeshInfo()
    geob.set(mesh_info)
    meshpy_mesh = build(mesh_info, max_volume=canonical_tet_volume)

    return np.array(meshpy_mesh.points), np.array(meshpy_mesh.elements)
Example #16
0
def main():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import (
        generate_surface_of_revolution,
        EXT_OPEN,
        GeometryBuilder,
    )

    r = 3

    points = 10
    dphi = pi / points

    def truncate(r):
        if abs(r) < 1e-10:
            return 0
        else:
            return r

    rz = [(truncate(r * sin(i * dphi)), r * cos(i * dphi))
          for i in range(points + 1)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(
        rz, closure=EXT_OPEN, radial_subdiv=10))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh = build(mesh_info)
    mesh.write_vtk("ball.vtk")
Example #17
0
def create_ball_mesh(num_longi_points=10):

    radius = 5.0

    radial_subdiv = 2 * num_longi_points

    dphi = np.pi / num_longi_points

    # Make sure the nodes meet at the poles of the ball.
    def truncate(r):
        if abs(r) < 1e-10:
            return 0
        else:
            return r

    # Compute the volume of a canonical tetrahedron
    # with edgelength radius*dphi.
    a = radius * dphi
    canonical_tet_volume = np.sqrt(2.0) / 12 * a**3

    # Build outline for surface of revolution.
    rz = [(truncate(radius * np.sin(i * dphi)), radius * np.cos(i * dphi))
          for i in range(num_longi_points + 1)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(
        rz, closure=EXT_OPEN, radial_subdiv=radial_subdiv))
    mesh_info = MeshInfo()
    geob.set(mesh_info)
    meshpy_mesh = build(mesh_info, max_volume=canonical_tet_volume)

    return np.array(meshpy_mesh.points), np.array(meshpy_mesh.elements)
Example #18
0
def test_tet_mesh(visualize=False):
    pytest.importorskip("meshpy")

    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import \
            GeometryBuilder, generate_surface_of_revolution, EXT_CLOSED_IN_RZ

    pytest.importorskip("meshpy")

    big_r = 3
    little_r = 1.5

    points = 50
    dphi = 2 * pi / points

    rz = np.array(
        [[big_r + little_r * cos(i * dphi), little_r * sin(i * dphi)]
         for i in range(points)])

    geo = GeometryBuilder()
    geo.add_geometry(*generate_surface_of_revolution(
        rz, closure=EXT_CLOSED_IN_RZ, radial_subdiv=20))

    mesh_info = MeshInfo()
    geo.set(mesh_info)

    mesh = build(mesh_info)

    def tet_face_vertices(vertices):
        return [
            (vertices[0], vertices[1], vertices[2]),
            (vertices[0], vertices[1], vertices[3]),
            (vertices[0], vertices[2], vertices[3]),
            (vertices[1], vertices[2], vertices[3]),
        ]

    face_map = {}
    for el_id, el in enumerate(mesh.elements):
        for fid, face_vertices in enumerate(tet_face_vertices(el)):
            face_map.setdefault(frozenset(face_vertices), []).append(
                (el_id, fid))

    adjacency = {}
    for face_vertices, els_faces in face_map.items():
        if len(els_faces) == 2:
            (e1, f1), (e2, f2) = els_faces
            adjacency.setdefault(e1, []).append(e2)
            adjacency.setdefault(e2, []).append(e1)

    cuts, part_vert = pymetis.part_graph(17, adjacency)

    if visualize:
        import pyvtk

        vtkelements = pyvtk.VtkData(
            pyvtk.UnstructuredGrid(mesh.points, tetra=mesh.elements), "Mesh",
            pyvtk.CellData(pyvtk.Scalars(part_vert, name="partition")))
        vtkelements.tofile('split.vtk')
def createSphere(center, R, m, n, mv=1):
    """
    The function computes the panelisation of a sphere using the predefined
    tools available in the Python module meshpy.
    
    INPUTS:
    - R:    radius of the sphere (m)
    - m:    number of radial subdivisions of the mesh (integer)
    - n:    number of circumferential subdivisions of the mesh (integer)
    - mv:   maxium valume of an element in the thetrahedral mesh 
            (the mesh is actually 3D but we only extract the surface panels)
    
    OUTPUTS:
    - verts:    coordinates of each vertices of the panelisation
    - faces:    triplets of indices representing the vertices of each triangular panel
    - tris:     triplets explicitly representing the coordinates of the vertices
                of each triangular face.
    """
    
    rz = []
    rz.append((0, R))
    for i in xrange(1, n):
        rz.append((R * np.sin(i * np.pi / n), R * np.cos(i * np.pi / n)))
    rz.append((0, -R))

    geob = GeometryBuilder() 
    geob.add_geometry(*generate_surface_of_revolution(rz, radial_subdiv=m)) 

    mesh_info = MeshInfo() 
    geob.set(mesh_info) 

    mesh = build(mesh_info, max_volume=mv) 

    verts = np.array(mesh.points)
    faces = np.array(mesh.faces)
    tris = verts[faces]
    bars = []
    return verts, bars, faces  # , tris
Example #20
0
def main():
    from ply import parse_ply
    import sys
    data = parse_ply(sys.argv[1])

    from meshpy.geometry import GeometryBuilder

    builder = GeometryBuilder()
    builder.add_geometry(points=[pt[:3] for pt in data["vertex"].data],
                         facets=[fd[0] for fd in data["face"].data])
    builder.wrap_in_box(1)

    from meshpy.tet import MeshInfo, build
    mi = MeshInfo()
    builder.set(mi)
    mi.set_holes([builder.center()])
    mesh = build(mi)
    print("%d elements" % len(mesh.elements))
    mesh.write_vtk("out.vtk")
Example #21
0
def test_torus():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import generate_surface_of_revolution, \
            EXT_CLOSED_IN_RZ, GeometryBuilder

    big_r = 3
    little_r = 2.9

    points = 50
    dphi = 2*pi/points

    rz = [(big_r+little_r*cos(i*dphi), little_r*sin(i*dphi))
            for i in range(points)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(rz,
            closure=EXT_CLOSED_IN_RZ, radial_subdiv=20))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    build(mesh_info)
Example #22
0
def create_ball_mesh(num_longi_points=10):

    radius = 5.0

    radial_subdiv = 2 * num_longi_points

    dphi = np.pi / num_longi_points

    # Make sure the nodes meet at the poles of the ball.
    def truncate(r):
        if abs(r) < 1e-10:
            return 0
        else:
            return r

    # Compute the volume of a canonical tetrahedron
    # with edgelength radius*dphi.
    a = radius * dphi
    canonical_tet_volume = np.sqrt(2.0) / 12 * a ** 3

    # Build outline for surface of revolution.
    rz = [
        (truncate(radius * np.sin(i * dphi)), radius * np.cos(i * dphi))
        for i in range(num_longi_points + 1)
    ]

    geob = GeometryBuilder()
    geob.add_geometry(
        *generate_surface_of_revolution(
            rz, closure=EXT_OPEN, radial_subdiv=radial_subdiv
        )
    )
    mesh_info = MeshInfo()
    geob.set(mesh_info)
    meshpy_mesh = build(mesh_info, max_volume=canonical_tet_volume)

    return np.array(meshpy_mesh.points), np.array(meshpy_mesh.elements)
Example #23
0
def main():
    from ply import parse_ply
    import sys
    data = parse_ply(sys.argv[1])

    from meshpy.geometry import GeometryBuilder

    builder = GeometryBuilder()
    builder.add_geometry(
            points=[pt[:3] for pt in data["vertex"].data],
            facets=[fd[0] for fd in data["face"].data])
    builder.wrap_in_box(1)

    from meshpy.tet import MeshInfo, build
    mi = MeshInfo()
    builder.set(mi)
    mi.set_holes([builder.center()])
    mesh = build(mi)
    print("%d elements" % len(mesh.elements))
    mesh.write_vtk("out.vtk")
Example #24
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)
Example #25
0
def main():
    import numpy
    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.3*numpy.ones(3, dtype=numpy.float64)
    points, facets, _, _ = \
            make_box(-extent_small, extent_small)

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

    points, facets, _, facet_markers = \
            make_box(numpy.array([-1, -1, -1]), numpy.array([1, 1, 5]))

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

    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
            [0, 0, 0] + [
                # region number
                1,
                # max volume in region
                0.001])

    mesh = build(mesh_info, max_volume=0.06,
            volume_constraints=True, attributes=True)
    print(("%d elements" % len(mesh.elements)))
    mesh.write_vtk("box-in-box.vtk")
Example #26
0
def main():
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import generate_surface_of_revolution, GeometryBuilder

    simple_rz = [
        (0, 0),
        (1, 1),
        (1, 2),
        (0, 3),
    ]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(simple_rz))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    # mesh_info.save_nodes("test")
    # mesh_info.save_poly("test")
    # mesh_info.load_poly("test")
    mesh = build(mesh_info)
    mesh.write_vtk("my_mesh.vtk")
Example #27
0
def test_2d_gauss_theorem(actx_factory):
    """Verify Gauss's theorem explicitly on a mesh"""

    pytest.importorskip("meshpy")

    from meshpy.geometry import make_circle, GeometryBuilder
    from meshpy.triangle import MeshInfo, build

    geob = GeometryBuilder()
    geob.add_geometry(*make_circle(1))
    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh_info = build(mesh_info)

    from meshmode.mesh.io import from_meshpy
    mesh = from_meshpy(mesh_info, order=1)

    actx = actx_factory()

    discr = DGDiscretizationWithBoundaries(actx, mesh, order=2)

    def f(x):
        return flat_obj_array(
                sym.sin(3*x[0])+sym.cos(3*x[1]),
                sym.sin(2*x[0])+sym.cos(x[1]))

    gauss_err = bind(discr,
            sym.integral((
                sym.nabla(2) * f(sym.nodes(2))
                ).sum())
            -  # noqa: W504
            sym.integral(
                sym.project("vol", sym.BTAG_ALL)(f(sym.nodes(2)))
                .dot(sym.normal(sym.BTAG_ALL, 2)),
                dd=sym.BTAG_ALL)
            )(actx)

    assert abs(gauss_err) < 1e-13
Example #28
0
def test_2d_gauss_theorem(actx_factory):
    """Verify Gauss's theorem explicitly on a mesh"""

    pytest.importorskip("meshpy")

    from meshpy.geometry import make_circle, GeometryBuilder
    from meshpy.triangle import MeshInfo, build

    geob = GeometryBuilder()
    geob.add_geometry(*make_circle(1))
    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh_info = build(mesh_info)

    from meshmode.mesh.io import from_meshpy
    from meshmode.mesh import BTAG_ALL

    mesh = from_meshpy(mesh_info, order=1)

    actx = actx_factory()

    dcoll = DiscretizationCollection(actx, mesh, order=2)
    volm_disc = dcoll.discr_from_dd(dof_desc.DD_VOLUME)
    x_volm = thaw(volm_disc.nodes(), actx)

    def f(x):
        return flat_obj_array(
            actx.np.sin(3 * x[0]) + actx.np.cos(3 * x[1]),
            actx.np.sin(2 * x[0]) + actx.np.cos(x[1]))

    f_volm = f(x_volm)
    int_1 = op.integral(dcoll, "vol", op.local_div(dcoll, f_volm))

    prj_f = op.project(dcoll, "vol", BTAG_ALL, f_volm)
    normal = thaw(dcoll.normal(BTAG_ALL), actx)
    int_2 = op.integral(dcoll, BTAG_ALL, prj_f.dot(normal))

    assert abs(int_1 - int_2) < 1e-13
Example #29
0
def createSphere(center, R, m, n, mv=1):
    """
    The function computes the panelisation of a sphere using the predefined
    tools available in the Python module meshpy.
    
    INPUTS:
    - R:    radius of the sphere (m)
    - m:    number of radial subdivisions of the mesh (integer)
    - n:    number of circumferential subdivisions of the mesh (integer)
    - mv:   maxium valume of an element in the thetrahedral mesh 
            (the mesh is actually 3D but we only extract the surface panels)
    
    OUTPUTS:
    - verts:    coordinates of each vertices of the panelisation
    - faces:    triplets of indices representing the vertices of each triangular panel
    - tris:     triplets explicitly representing the coordinates of the vertices
                of each triangular face.
    """

    rz = []
    rz.append((0, R))
    for i in xrange(1, n):
        rz.append((R * np.sin(i * np.pi / n), R * np.cos(i * np.pi / n)))
    rz.append((0, -R))

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(rz, radial_subdiv=m))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    mesh = build(mesh_info, max_volume=mv)

    verts = np.array(mesh.points)
    faces = np.array(mesh.faces)
    tris = verts[faces]
    bars = []
    return verts, bars, faces  # , tris
Example #30
0
def test_torus():
    from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import generate_surface_of_revolution, \
            EXT_CLOSED_IN_RZ, GeometryBuilder

    big_r = 3
    little_r = 2.9

    points = 50
    dphi = 2 * pi / points

    rz = [(big_r + little_r * cos(i * dphi), little_r * sin(i * dphi))
          for i in range(points)]

    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(
        rz, closure=EXT_CLOSED_IN_RZ, radial_subdiv=20))

    mesh_info = MeshInfo()
    geob.set(mesh_info)

    build(mesh_info)
Example #31
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)
Example #32
0
 def __init__(self):
     self.geob = GeometryBuilder()
Example #33
0
class GeometryMeshPyTetgen(GeometryMeshPy):
    """Define and mesh 3-dimensional domains with MeshPy/Tetgen."""
    def __init__(self):
        self.geob = GeometryBuilder()

    def mesh(self, h, holes=None):
        info = meshpy.tet.MeshInfo()
        self.geob.set(info)
        if holes is not None:
            info.set_holes(holes)
        self.m = meshpy.tet.build(info, max_volume=h**3)
        return self._mesh_output()

    def extrude(self, points, z):
        """A wrapper to self.advanced_extrude to create
        a simple extrusion of a cross section.
        
        Parameters
        ==========
        points : array of tuples
            An array of tuples with (x,y)-coordinates of the boundary
            points. The boundary points are connected by straight
            line segments. The last point is connected to the first
            point.
        z : float
            The extrusion length.
        """
        self.advanced_extrude(points, [(0., 0.), (1., 0.), (1., z), (0., z)])

    def advanced_extrude(self, points, rz):
        """Add a geometry defined by an extrusion.
        
        Parameters
        ==========
        points : array of tuples
            An array of tuples with (x,y)-coordinates of the boundary
            points. The boundary points are connected by straight
            line segments. The last point is connected to the first
            point.
        rz : array of tuples
            An array of tuples with (r,z)-coordinates. The first
            number of each tuple acts as a multiplier to increase
            or decrease the size of the cross section. The second
            number defines the z-location of the cross section.
        """
        self.geob.add_geometry(*meshpy.geometry.generate_extrusion(
            rz_points=rz, base_shape=points))

    def revolution(self, points, N, transform=None):
        """Generate a surface of revolution.

        Parameters
        ==========
        points : array of tuples
            An array of tuples with (x,y)-coordinates of the boundary
            points of the to-be-revolved surface. The boundary points
            are connected by straight line segments. The revolution is
            performed around y-axis. The first and the last points should
            be located at x=0.
        N : integer
            The number of subdivisions in the revolution.
        transform : (OPTIONAL) A function that takes list of 3-tuples
            and modifies the list somehow. Can be used to e.g. translate
            the points after revolving.
        """
        if transform is None:
            self.geob.add_geometry(
                *meshpy.geometry.generate_surface_of_revolution(
                    points, closure=meshpy.geometry.EXT_OPEN, radial_subdiv=N))
        else:
            a, b, c, d = meshpy.geometry.generate_surface_of_revolution(
                points, closure=meshpy.geometry.EXT_OPEN, radial_subdiv=N)
            A = [transform(*x) for x in a]
            self.geob.add_geometry(A, b, c, d)
Example #34
0
def test_convergence_advec(ctx_factory,
                           mesh_name,
                           mesh_pars,
                           op_type,
                           flux_type,
                           order,
                           visualize=False):
    """Test whether 2D advection actually converges"""

    cl_ctx = ctx_factory()
    queue = cl.CommandQueue(cl_ctx)
    actx = PyOpenCLArrayContext(queue)

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    for mesh_par in mesh_pars:
        if mesh_name == "segment":
            from meshmode.mesh.generation import generate_box_mesh
            mesh = generate_box_mesh([np.linspace(-1.0, 1.0, mesh_par)],
                                     order=order)

            dim = 1
            dt_factor = 1.0
        elif mesh_name == "disk":
            pytest.importorskip("meshpy")

            from meshpy.geometry import make_circle, GeometryBuilder
            from meshpy.triangle import MeshInfo, build

            geob = GeometryBuilder()
            geob.add_geometry(*make_circle(1))
            mesh_info = MeshInfo()
            geob.set(mesh_info)

            mesh_info = build(mesh_info, max_volume=mesh_par)

            from meshmode.mesh.io import from_meshpy
            mesh = from_meshpy(mesh_info, order=1)
            dim = 2
            dt_factor = 4
        elif mesh_name.startswith("rect"):
            dim = int(mesh_name[4:])
            from meshmode.mesh.generation import generate_regular_rect_mesh
            mesh = generate_regular_rect_mesh(a=(-0.5, ) * dim,
                                              b=(0.5, ) * dim,
                                              n=(mesh_par, ) * dim,
                                              order=4)

            if dim == 2:
                dt_factor = 4
            elif dim == 3:
                dt_factor = 2
            else:
                raise ValueError("dt_factor not known for %dd" % dim)

        else:
            raise ValueError("invalid mesh name: " + mesh_name)

        v = np.array([0.27, 0.31, 0.1])[:dim]
        norm_v = la.norm(v)

        def f(x):
            return sym.sin(10 * x)

        def u_analytic(x):
            return f(-v.dot(x) / norm_v + sym.var("t", sym.DD_SCALAR) * norm_v)

        from grudge.models.advection import (StrongAdvectionOperator,
                                             WeakAdvectionOperator)
        discr = DGDiscretizationWithBoundaries(actx, mesh, order=order)
        op_class = {
            "strong": StrongAdvectionOperator,
            "weak": WeakAdvectionOperator,
        }[op_type]
        op = op_class(v,
                      inflow_u=u_analytic(sym.nodes(dim, sym.BTAG_ALL)),
                      flux_type=flux_type)

        bound_op = bind(discr, op.sym_operator())

        u = bind(discr, u_analytic(sym.nodes(dim)))(actx, t=0)

        def rhs(t, u):
            return bound_op(t=t, u=u)

        if dim == 3:
            final_time = 0.1
        else:
            final_time = 0.2

        h_max = bind(discr, sym.h_max_from_volume(discr.ambient_dim))(actx)
        dt = dt_factor * h_max / order**2
        nsteps = (final_time // dt) + 1
        dt = final_time / nsteps + 1e-15

        from grudge.shortcuts import set_up_rk4
        dt_stepper = set_up_rk4("u", dt, u, rhs)

        last_u = None

        from grudge.shortcuts import make_visualizer
        vis = make_visualizer(discr, vis_order=order)

        step = 0

        for event in dt_stepper.run(t_end=final_time):
            if isinstance(event, dt_stepper.StateComputed):
                step += 1
                logger.debug("[%04d] t = %.5f", step, event.t)

                last_t = event.t
                last_u = event.state_component

                if visualize:
                    vis.write_vtk_file("fld-%s-%04d.vtu" % (mesh_par, step),
                                       [("u", event.state_component)])

        error_l2 = bind(discr,
                        sym.norm(2,
                                 sym.var("u") - u_analytic(sym.nodes(dim))))(
                                     t=last_t, u=last_u)
        logger.info("h_max %.5e error %.5e", h_max, error_l2)
        eoc_rec.add_data_point(h_max, error_l2)

    logger.info(
        "\n%s", eoc_rec.pretty_print(abscissa_label="h",
                                     error_label="L2 Error"))

    assert eoc_rec.order_estimate() > order
Example #35
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 grudge.mesh import make_conformal_mesh_ext

    vertices = numpy.asarray(mesh.points, order="C")
    from grudge.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")]
    )
Example #36
0
class FyberModel:
    """
    Full Fiber Model
    Can store all material and geometric properties
    Can run pushover of model
    Can display results in a variety of ways
    """
    def __init__(self, figsize=6):
        # Material Properties
        self.materials = {}
        # Mesh Properties
        self.builder = GeometryBuilder()
        self.reinforcement = []
        self.outer_facets = []
        self.mesh_areas = {}
        self.mesh_centroids = {}
        self.mesh = None
        # Data structure to assign material ids after mesh generation
        self.ele_mat_primitive = []
        self.ele_mat = {}
        # Load step Data
        self.load_angle = 0
        self.phi_list = []
        self.M_list = []
        # States of all elements at each load step from analysis
        self.state_id = 0
        self.states = {}
        self.state_y_loc = {}
        self.analysis_model = FiberModel()
        # Failure check for end of analysis (conf crush/ bar fracture)
        self.fail = False
        # Plot settings
        self.figsize = figsize

    @staticmethod
    def conf_pressure(shape, **kwargs):
        """Technically static method, but I just want one import"""
        if shape == 'circle':
            return conf_pressure_circle(kwargs['fyh'], kwargs['bar'],
                                        kwargs['s'], kwargs['D'])
        elif shape == 'rect':
            return conf_pressure_rect(kwargs['fyh'], kwargs['bar'],
                                      kwargs['s'], kwargs['b'], kwargs['w'],
                                      kwargs['nx'], kwargs['ny'])
        else:
            exit(
                "I can only find the confining pressure of 'circle' or 'rect'")

    @staticmethod
    def color_from_state(state):
        """Not sure how I want to store the states for now, so i'll just hold the options in this function"""
        colors = [
            "Gray", "Purple", "Pink", "Blue", "Black", "Green", "Yellow",
            "Red", "White"
        ]
        if type(state) == int:
            return colors[state]
        else:
            return state

    def add_material(self, mat_num, mat, **kwargs):
        """Add materials for unconfined concrete, confined concrete, or steel"""
        if mat == 'concrete':
            if 'fple' in kwargs:
                self.materials[mat_num] = ConfConcMat(kwargs)
            else:
                self.materials[mat_num] = UnconfConcMat(kwargs)
        elif mat == 'steel':
            self.materials[mat_num] = SteelMat(kwargs['E'], kwargs['fy'],
                                               kwargs['fsu'], kwargs['e_sh'],
                                               kwargs['e_su'], kwargs['P'])
        elif mat == 'user':
            if 'mirror' in kwargs:
                self.materials[mat_num] = UserMat(kwargs['points'],
                                                  kwargs['mirror'])
            else:
                self.materials[mat_num] = UserMat(kwargs['points'])
        else:
            exit("'{}' is not a material type I recognize".format(mat))

    def add_geometry(self, shape, mat_id, **kwargs):
        if shape == 'circle':
            self.builder.add_geometry(*make_circle(kwargs['D'] /
                                                   2, kwargs['c']))
            self.ele_mat_primitive.append(
                (kwargs['D'] / 2, kwargs['c'], mat_id))
            if not self.outer_facets:
                # list empty - first points
                self.outer_facets = self.builder.facets
            # self.mesh_points.extend(builder.points)
        elif shape == 'rectangle':
            # TODO CHANGE TO builder.add_geometry(*make_rectangle)
            # TODO add rect primitive
            # self.mesh_points.extend(gen_rect_points(c, W, H))
            print("I can only currently add type='circle' reinforcement")
            exit()
        else:
            print("'{}' is not a geometry type I recognize".format(shape))
            exit()

    def add_reinforcement(self, shape, mat_id, **kwargs):
        """Add reinforcement in a circle (for now), confine concrete inside if needed"""
        if shape == 'circle':
            if 'conf_id' in kwargs:
                reinforcement_builder = GeometryBuilder()
                reinforcement_builder.add_geometry(
                    *make_circle(kwargs['D'] /
                                 2, kwargs['c'], kwargs['count']))
                r = ReinforcementProperties(reinforcement_builder.points,
                                            kwargs['bar'], mat_id)
                self.reinforcement.append(r)
                # Add points for confinement into mesh
                self.builder.add_geometry(*make_circle(kwargs['D'] /
                                                       2, kwargs['c']))
                self.ele_mat_primitive.append(
                    (kwargs['D'] / 2, kwargs['c'], kwargs['conf_id']))
            else:
                reinforcement_builder = GeometryBuilder()
                reinforcement_builder.add_geometry(
                    *make_circle(kwargs['D'] /
                                 2, kwargs['c'], kwargs['count']))
                r = ReinforcementProperties(reinforcement_builder.points,
                                            kwargs['bar'], mat_id)
                self.reinforcement.append(r)
        else:
            # Rectangular reinforcement
            # not implemented for now
            print("I can only currently add type='circle' reinforcement")
            exit()

    def set_load(self, load_type, **kwargs):
        """Add axial load and moment increment/angle"""
        if load_type == 'Axial':
            self.analysis_model.P = kwargs['P']
        elif load_type == 'Moment':
            self.analysis_model.M = kwargs['M']
        else:
            print("This is not a load type I recognize")
            exit()

    def generate_mesh(self, mesh_size=5):
        """Setup Mesh Object and Properties
        Go through generation Builder -> MeshInfo -> Mesh"""
        # TODO Look into section-properties on github?
        # TODO Are the values from meshpy.triangle accurate?
        mesh_info = MeshInfo()
        self.builder.set(mesh_info)
        self.mesh = build(mesh_info, max_volume=mesh_size)
        # Calculate Element Centroids
        # C = [(x1+x2+x3)/3 , (y1+y2+y3)/3]
        for i, e in enumerate(self.mesh.elements):
            p1 = self.mesh.points[e[0]]
            p2 = self.mesh.points[e[1]]
            p3 = self.mesh.points[e[2]]
            self.mesh_centroids[i] = ((p1[0] + p2[0] + p3[0]) / 3,
                                      (p1[1] + p2[1] + p3[1]) / 3)
        # Calculate Element Areas
        # A = abs(x1*y2 + x2*y3 + x3*y1 - y1*x2 - y2*x3 - y3*x1)/2
        for i, e in enumerate(self.mesh.elements):
            p1 = self.mesh.points[e[0]]
            p2 = self.mesh.points[e[1]]
            p3 = self.mesh.points[e[2]]
            self.mesh_areas[i] = abs(p1[0] * p2[1] + p2[0] * p3[1] +
                                     p3[0] * p1[1] - p1[1] * p2[0] -
                                     p2[1] * p3[0] - p3[1] * p1[0]) / 2
        # Assign material ids to elements
        # A bit verbose just to show calculations - might change later
        # this only accounts for circle assignments
        for primitive in self.ele_mat_primitive:
            r = primitive[0]
            prim_c = primitive[1]
            mat_id = primitive[2]
            for n, c in self.mesh_centroids.items():
                if hypot(c[0] - prim_c[0], c[1] - prim_c[1]) < r:
                    self.ele_mat[n] = mat_id

    def gen_fiber_model(self):
        # We can re-mesh our geometry, but our reinforcement is just points
        # So when we add the reinforcement we should also make holes in mesh (TODO)
        max_y = 0
        min_y = 0
        for n in self.mesh_centroids.keys():
            centroid = self.mesh_centroids[n]
            area = self.mesh_areas[n]
            self.analysis_model.fibers[n] = Fiber(area, centroid,
                                                  self.ele_mat[n])
            max_y = max(max_y, centroid[1])
            min_y = min(min_y, centroid[1])
        self.analysis_model.maxy = max_y
        self.analysis_model.miny = min_y
        meh = max(self.mesh_centroids.keys())
        n = 1
        for reinforce_group in self.reinforcement:
            for centroid in reinforce_group.points:
                # TODO - SHOULD I HAVE PATCHES REGARDLESS OF MAT/reinforcement?
                # MIGHT BE PROBLEM IF NEED VALUES FROM A SINGLE BAR
                # MAYBE SET MAX VOLUME SEPARATELY?
                self.analysis_model.fibers[n + meh] = Fiber(
                    reinforce_group.area, centroid, reinforce_group.mat_id)
                n += 1
        self.analysis_model.materials = self.materials
        # Generate Initial States
        self.states[0] = State([0] * len(self.mesh.elements) + [8] * (n - 1),
                               0, 0, 0)
        self.phi_list = [0]
        self.M_list = [0]

    def analyze(self):
        """Analyze a fiber model with given load step"""
        # setup the model with the current mesh discretization
        self.gen_fiber_model()
        # TODO allow step change?
        # delta_phi = 5e-6
        delta_phi = 1e-5
        for step in range(1, 1000):
            # Setup this step to run equilibrium analysis
            phi = step * delta_phi
            self.analysis_model.phi = phi
            # I'm not sure if scipy.optimize.newton can fail here, might need to catch exception with bisection
            zero_strain = newton(self.analysis_model.force_balance,
                                 self.analysis_model.zero_strain_location)
            self.analysis_model.zero_strain_location = zero_strain
            # Get Moment at current state
            moment = self.analysis_model.calc_moment()
            # Generate state data and save this load step results
            self.phi_list.append(round(phi, 8))
            self.M_list.append(moment)
            self.states[step] = self.analysis_model.state
            # self.state_y_loc[step] = self.analysis_model.states
            if self.analysis_model.fail:
                print(
                    f"Analysis ended at phi={round(phi, 8)}\nFailure: {self.analysis_model.fail}"
                )
                break
            # Don't necessarily want to break for tension failure - Say, if entire section is steel
            # if M < 1:
            #   print("Capacity of entire section failed")
            #   break

    def display_material(self, mat_id, loc=None):
        # Plot a specific material with tag mat_id
        material = self.materials[mat_id]
        tmp_strains = material.useful_points
        useful_strains = []
        for point in tmp_strains:
            useful_strains.append(point - 1e-6)
            useful_strains.append(point)
            useful_strains.append(point + 1e-6)
        lin_strains = np.linspace(material.useful_points[0],
                                  material.useful_points[-1], 30)
        strains = np.sort(np.r_[lin_strains, useful_strains[1:-1]])
        stresses = []
        colors = []
        for strain in strains:
            stresses.append(material.stress(strain))
            colors.append(self.color_from_state(material.state))
        stresses = np.array(stresses)
        stresses[stresses == 0] = np.nan
        fig, ax = plt.subplots()
        # Setup Plot - Discrete between colors
        i = 0
        x = []
        y = []
        color = colors[0]
        while True:
            new_color = colors[i]
            x.append(strains[i])
            y.append(stresses[i])
            if new_color != color or i == len(strains) - 1:
                ax.plot(x, y, c=color)
                color = new_color
                x = [strains[i]]
                y = [stresses[i]]
                if i == len(strains) - 1:
                    break
                i -= 1
            i += 1
        # Axis Options
        if loc is not None:
            # Plot some location
            ax.plot(loc[0], loc[1], 'ro')
        ax.set_title("Material Stress Strain id={}".format(mat_id))
        ax.set_xlabel('Strain (in/in)')
        ax.set_ylabel('Stress (ksi)')
        ax.grid()

    def display_materials(self, mat_id=None, loc=None):
        """Plot all loaded materials to verify stress strain curves"""
        if mat_id is None:
            # Plot standard -> all material plots
            for mat_id, material in self.materials.items():
                self.display_material(mat_id, loc)
        else:
            self.display_material(mat_id, loc)
        plt.show()

    def display_mesh(self):
        """Show the current geometry and mesh (equivalent to step zero of display_mc)"""
        fig, ax = plt.subplots(figsize=(self.figsize, self.figsize))
        patches = []
        for i, pt_ids in enumerate(self.mesh.elements):
            p = [self.mesh.points[pt_id] for pt_id in pt_ids]
            new_patch = plt.Polygon(p, fc="Gray", ec='black', zorder=0)
            patches.append(new_patch)
            ax.add_patch(new_patch)
        for reinforce_group in self.reinforcement:
            for centroids in reinforce_group.points:
                new_patch = CirclePolygon(centroids,
                                          reinforce_group.radius,
                                          8,
                                          fc='White',
                                          ec='black',
                                          zorder=15)
                patches.append(new_patch)
                ax.add_patch(new_patch)
        # Plot nodal points of mesh (useful to auto set axes limits)
        ax.scatter(*zip(*self.mesh.points), c='black', s=4, zorder=5)
        plt.show()

    def mc_gif(self):
        """Testing saving as gif"""
        fig, (ax, ax_mc) = plt.subplots(1,
                                        2,
                                        figsize=(self.figsize * 2,
                                                 self.figsize))
        polygons = []
        for element in self.mesh.elements:
            poly_pts = [self.mesh.points[i] for i in element]
            polygons.append(poly_pts)
        patches = []
        # Draw Polygons for mesh and reinforcement
        i = 0
        for p in polygons:
            new_patch = plt.Polygon(p,
                                    fc='Grey',
                                    ec='Black',
                                    zorder=0,
                                    picker=.01,
                                    gid=str(i))
            patches.append(new_patch)
            ax.add_patch(new_patch)
            i += 1
        if self.reinforcement:
            for reinforcement_group in self.reinforcement:
                for centroid in reinforcement_group.points:
                    new_patch = CirclePolygon(centroid,
                                              reinforcement_group.radius,
                                              8,
                                              fc='White',
                                              ec='Black',
                                              zorder=15,
                                              picker=.01,
                                              gid=str(i))
                    patches.append(new_patch)
                    ax.add_patch(new_patch)
                    i += 1
        # Plot nodal points of mesh (useful to auto set axes limits)
        ax.scatter(*zip(*self.mesh.points), c='black', s=4, zorder=5)
        num_steps = len(self.states) - 1
        # LEFT MC Plot
        ax_mc.plot(self.phi_list, self.M_list, 'k')
        ax.axis('equal')
        # Location indicator as patch so we can update it easily
        # Ellipse b/c we don't have equal axis ranges for phi/M
        point = Ellipse((0, 0),
                        max(self.phi_list) / 50,
                        max(self.M_list) / 50,
                        fc='red',
                        zorder=10)
        ax_mc.add_patch(point)
        # Scientific notation for phi values
        ax_mc.ticklabel_format(axis='x',
                               style='sci',
                               scilimits=(-2, 2),
                               useMathText=True)

        # Setup Sliders for intractability to look through results
        def update(state):
            state = int(state)
            self.state_id = int(state)
            # Update Patch  colors
            state_colors = [
                self.color_from_state(state)
                for state in self.states[state].mat_state
            ]
            for patch, color in zip(patches, state_colors):
                patch.set_facecolor(color)
            point.center = (self.phi_list[state], self.M_list[state])
            # fig.canvas.draw_idle()

        ax_slider = plt.axes([0.117, 0.01, 0.79, 0.02], facecolor='White')
        slider_fct = Slider(ax_slider,
                            'STEP',
                            0,
                            num_steps,
                            valinit=0,
                            valstep=1,
                            valfmt='%i')
        slider_fct.on_changed(update)

        def frame(state):
            # Set State - Updates everything
            slider_fct.set_val(state)

        print(
            "Saving animated gif. This will take a while and take several dozen megs of space.\n"
            "It's saving full frames and not optimizing.")
        test = anim.FuncAnimation(fig, frame, frames=len(self.states))
        test.save("Moment_Curvature.gif", fps=16)

    def display_mc(self):
        """Plot the moment curvature, and interactive section viewer"""
        # TODO SEPARATE PLOT FOR FORCE/STRESS DISTRIBUTION?
        # TODO PATCH COLLECTION FOR INSTANTANEOUS? COLOR UPDATE?
        fig, (ax, ax_mc) = plt.subplots(1,
                                        2,
                                        figsize=(self.figsize * 2,
                                                 self.figsize))
        polygons = []
        for element in self.mesh.elements:
            poly_pts = [self.mesh.points[i] for i in element]
            polygons.append(poly_pts)
        patches = []
        # Draw Polygons for mesh and reinforcement
        i = 0
        for p in polygons:
            new_patch = plt.Polygon(p,
                                    fc="Gray",
                                    ec='black',
                                    zorder=0,
                                    picker=.01,
                                    gid=str(i))
            patches.append(new_patch)
            ax.add_patch(new_patch)
            i += 1
        if self.reinforcement:
            for reinforce_group in self.reinforcement:
                for centroid in reinforce_group.points:
                    new_patch = CirclePolygon(centroid,
                                              reinforce_group.radius,
                                              8,
                                              fc='White',
                                              ec='black',
                                              zorder=15,
                                              picker=.01,
                                              gid=str(i))
                    patches.append(new_patch)
                    ax.add_patch(new_patch)
                    i += 1
        # Plot nodal points of mesh (useful to auto set axes limits)
        ax.scatter(*zip(*self.mesh.points), c='black', s=4, zorder=5)
        num_steps = len(self.states) - 1
        # LEFT MC Plot
        ax_mc.plot(self.phi_list, self.M_list, 'k')
        ax.axis('equal')
        # Location indicator as patch so we can update it easily
        # Ellipse b/c we don't have equal axis ranges for phi/M
        point = Ellipse((0, 0),
                        max(self.phi_list) / 50,
                        max(self.M_list) / 50,
                        fc='red',
                        zorder=10)
        ax_mc.add_patch(point)
        # Scientific notation for phi values
        ax_mc.ticklabel_format(axis='x',
                               style='sci',
                               scilimits=(-2, 2),
                               useMathText=True)

        # Setup Sliders for intractability to look through results
        def update(phi_step):
            phi_step = int(phi_step)
            self.state_id = int(phi_step)
            # Update Patch  colors
            state_colors = [
                self.color_from_state(state)
                for state in self.states[phi_step].mat_state
            ]
            for patch, color in zip(patches, state_colors):
                patch.set_facecolor(color)
            point.center = (self.phi_list[phi_step], self.M_list[phi_step])
            fig.canvas.draw_idle()

        ax_slider = plt.axes([0.117, 0.01, 0.79, 0.02], facecolor='White')
        slider_fct = Slider(ax_slider,
                            'STEP',
                            0,
                            num_steps,
                            valinit=0,
                            valstep=1,
                            valfmt='%i')
        slider_fct.on_changed(update)

        # Setup mesh onclick event to view stress/strain location of each fiber
        def onclick(event):
            # print(event.mouseevent.__dict__)
            # print(event.artist.__dict__)
            # print(event.canvas.__dict__)
            patch_id = int(event.artist._gid)
            strain = self.states[self.state_id].strains[patch_id]
            stress = self.states[self.state_id].stresses[patch_id]
            self.display_materials(self.ele_mat[patch_id], (strain, stress))
            return True

        fig.canvas.mpl_connect('pick_event', onclick)

        plt.show()

    def display_mc_2x2(self):
        """Plot the moment curvature, and interactive section viewer"""
        # TODO SEPARATE PLOT FOR FORCE/STRESS DISTRIBUTION?
        # TODO PATCH COLLECTION FOR INSTANTANEOUS? COLOR UPDATE?
        fig, axes = plt.subplots(2,
                                 2,
                                 figsize=(self.figsize * 1.5,
                                          self.figsize * 1.5))
        ax = axes[0, 0]
        ax_mc = axes[0, 1]
        ax_strain = axes[1, 0]
        ax_stress = axes[1, 1]
        polygons = []
        for element in self.mesh.elements:
            poly_pts = [self.mesh.points[i] for i in element]
            polygons.append(poly_pts)
        patches = []
        # Draw Polygons for mesh and reinforcement
        i = 0
        for p in polygons:
            new_patch = plt.Polygon(p,
                                    fc="Gray",
                                    ec='black',
                                    zorder=0,
                                    picker=.01,
                                    gid=str(i))
            patches.append(new_patch)
            ax.add_patch(new_patch)
            i += 1
        if self.reinforcement:
            for reinforce_group in self.reinforcement:
                for centroid in reinforce_group.points:
                    new_patch = CirclePolygon(centroid,
                                              reinforce_group.radius,
                                              8,
                                              fc='White',
                                              ec='black',
                                              zorder=15,
                                              picker=.01,
                                              gid=str(i))
                    patches.append(new_patch)
                    ax.add_patch(new_patch)
                    i += 1
        # Plot nodal points of mesh (useful to auto set axes limits)
        ax.scatter(*zip(*self.mesh.points), c='black', s=4, zorder=5)
        num_steps = len(self.states) - 1
        # LEFT MC Plot
        ax_mc.plot(self.phi_list, self.M_list, 'k')
        ax.axis('equal')
        # Location indicator as patch so we can update it easily
        # Ellipse b/c we don't have equal axis ranges for phi/M
        point = Ellipse((0, 0),
                        max(self.phi_list) / 50,
                        max(self.M_list) / 50,
                        fc='red',
                        zorder=10)
        ax_mc.add_patch(point)
        # Scientific notation for phi values
        ax_mc.ticklabel_format(axis='x',
                               style='sci',
                               scilimits=(-2, 2),
                               useMathText=True)

        line = line2 = line3 = None

        # Setup Sliders for intractability to look through results
        def update(phi_step):
            phi_step = int(phi_step)
            self.state_id = int(phi_step)
            # Update Patch  colors
            state_colors = [
                self.color_from_state(state)
                for state in self.states[phi_step].mat_state
            ]
            for patch, color in zip(patches, state_colors):
                patch.set_facecolor(color)
            point.center = (self.phi_list[phi_step], self.M_list[phi_step])

            x = [
                self.states[phi_step].min_strain,
                self.states[phi_step].max_strain
            ]
            y = [self.analysis_model.miny, self.analysis_model.maxy]

            line.set_data(x, y)
            line2.set_data(
                [-1, 1],
                [self.states[phi_step].y_loc, self.states[phi_step].y_loc])
            line3.set_data([
                self.analysis_model.miny * 1.1, self.analysis_model.maxy * 1.1
            ], [self.states[phi_step].y_loc, self.states[phi_step].y_loc])
            fig.canvas.draw_idle()

        # Setup mesh onclick event to view stress/strain location of each fiber
        def onclick(event):
            # print(event.mouseevent.__dict__)
            # print(event.artist.__dict__)
            # print(event.canvas.__dict__)
            patch_id = int(event.artist._gid)
            strain = self.states[self.state_id].strains[patch_id]
            stress = self.states[self.state_id].stresses[patch_id]
            self.display_materials(self.ele_mat[patch_id], (strain, stress))
            return True

        fig.canvas.mpl_connect('pick_event', onclick)

        ax_slider = plt.axes([0.117, 0.01, 0.79, 0.02], facecolor='white')
        slider_fct = Slider(ax_slider,
                            'STEP',
                            0,
                            num_steps,
                            valinit=0,
                            valstep=1,
                            valfmt='%i')
        slider_fct.on_changed(update)

        # Strain plot
        ax_strain.plot([0, 0],
                       [self.analysis_model.miny, self.analysis_model.maxy],
                       'k')
        ax_strain.set_xlim([
            self.states[len(self.states) - 1].min_strain * 1.05,
            self.states[len(self.states) - 1].max_strain * 1.05
        ])

        line, = ax_strain.plot(
            [0, 0], [self.analysis_model.miny, self.analysis_model.maxy],
            color='Red')
        phi_step_init = 0
        line2, = ax_strain.plot([-1, 1], [
            self.states[phi_step_init].y_loc, self.states[phi_step_init].y_loc
        ],
                                color='Blue')
        line3, = ax.plot(
            [self.analysis_model.miny * 1.1, self.analysis_model.maxy * 1.1], [
                self.states[phi_step_init].y_loc,
                self.states[phi_step_init].y_loc
            ],
            color='Red')

        # Stress Plot
        ax_stress.plot([0, 0],
                       [self.analysis_model.miny, self.analysis_model.maxy],
                       'k')
        ax_stress.text(0, 0,
                       "This Plot Was\nIntentionally Left Blank\n(For Now)")

        plt.tight_layout()
        # plt.tight_layout(rect=[0, .05, 1, 1])
        plt.show()

    def export_results(self, filename=''):
        out = ["phi,M"]
        for phi, M in zip(self.phi_list, self.M_list):
            out.append(f"{phi},{M}")
        if filename == '':
            print("\n".join(out))
        else:
            with open(filename, 'w') as f:
                f.write("\n".join(out))
Example #37
0
class GeometryMeshPyTetgen(GeometryMeshPy):
    """Define and mesh 3-dimensional domains with MeshPy/Tetgen."""

    def __init__(self):
        self.geob=GeometryBuilder()

    def mesh(self,h,holes=None):
        info=meshpy.tet.MeshInfo()
        self.geob.set(info)
        if holes is not None:
            info.set_holes(holes)
        self.m=meshpy.tet.build(info,max_volume=h**3)
        return self._mesh_output()

    def extrude(self,points,z):
        """A wrapper to self.advanced_extrude to create
        a simple extrusion of a cross section.
        
        Parameters
        ==========
        points : array of tuples
            An array of tuples with (x,y)-coordinates of the boundary
            points. The boundary points are connected by straight
            line segments. The last point is connected to the first
            point.
        z : float
            The extrusion length.
        """
        self.advanced_extrude(points,[(0.,0.),(1.,0.),(1.,z),(0.,z)])

    def advanced_extrude(self,points,rz):
        """Add a geometry defined by an extrusion.
        
        Parameters
        ==========
        points : array of tuples
            An array of tuples with (x,y)-coordinates of the boundary
            points. The boundary points are connected by straight
            line segments. The last point is connected to the first
            point.
        rz : array of tuples
            An array of tuples with (r,z)-coordinates. The first
            number of each tuple acts as a multiplier to increase
            or decrease the size of the cross section. The second
            number defines the z-location of the cross section.
        """
        self.geob.add_geometry(*meshpy.geometry.generate_extrusion(rz_points=rz,
            base_shape=points))

    def revolution(self,points,N,transform=None):
        """Generate a surface of revolution.

        Parameters
        ==========
        points : array of tuples
            An array of tuples with (x,y)-coordinates of the boundary
            points of the to-be-revolved surface. The boundary points
            are connected by straight line segments. The revolution is
            performed around y-axis. The first and the last points should
            be located at x=0.
        N : integer
            The number of subdivisions in the revolution.
        transform : (OPTIONAL) A function that takes list of 3-tuples
            and modifies the list somehow. Can be used to e.g. translate
            the points after revolving.
        """
        if transform is None:
            self.geob.add_geometry(*meshpy.geometry.generate_surface_of_revolution(points,
                closure=meshpy.geometry.EXT_OPEN,radial_subdiv=N))
        else:
            a,b,c,d=meshpy.geometry.generate_surface_of_revolution(points,
                    closure=meshpy.geometry.EXT_OPEN,radial_subdiv=N)
            A=[transform(*x) for x in a]
            self.geob.add_geometry(A,b,c,d)
Example #38
0
 def __init__(self):
     self.geob=GeometryBuilder()
Example #39
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)
    vtkelements.tofile(filename)


def area_of_tri(nodes):
    v1 = np.array(nodes[0].coord[:2]) - np.array(nodes[1].coord[:2])
    v2 = np.array(nodes[0].coord[:2]) - np.array(nodes[2].coord[:2])
    area = np.cross(v1, v2) / 2.
    return area


if __name__ == "__main__":
    #mesh
    r = 1
    l = 2
    rz = [(0, 0), (r, 0), (r, l), (0, l)]
    geob = GeometryBuilder()
    geob.add_geometry(*generate_surface_of_revolution(
        rz, radial_subdiv=20, ring_markers=[1, 2, 3]))
    mesh_info = MeshInfo()
    geob.set(mesh_info)
    mesh = build(mesh_info, max_volume=0.01)

    E = 210e6
    nu = 0.3
    P = 2000
    points = np.array(mesh.points)
    cells = np.array(mesh.elements)
    face_cells = np.array(mesh.faces)
    z_face0_cells = [
        c for c in face_cells if np.isclose(points[c][:, 2], 0).all()
    ]
Example #41
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 grudge.mesh import make_conformal_mesh
    return make_conformal_mesh(mesh.points, mesh.elements, bdry_tagger)
Example #42
0
def test_convergence_advec(actx_factory,
                           mesh_name,
                           mesh_pars,
                           op_type,
                           flux_type,
                           order,
                           visualize=False):
    """Test whether 2D advection actually converges"""

    actx = actx_factory()

    from pytools.convergence import EOCRecorder
    eoc_rec = EOCRecorder()

    for mesh_par in mesh_pars:
        if mesh_name == "segment":
            mesh = mgen.generate_box_mesh([np.linspace(-1.0, 1.0, mesh_par)],
                                          order=order)

            dim = 1
            dt_factor = 1.0
        elif mesh_name == "disk":
            pytest.importorskip("meshpy")

            from meshpy.geometry import make_circle, GeometryBuilder
            from meshpy.triangle import MeshInfo, build

            geob = GeometryBuilder()
            geob.add_geometry(*make_circle(1))
            mesh_info = MeshInfo()
            geob.set(mesh_info)

            mesh_info = build(mesh_info, max_volume=mesh_par)

            from meshmode.mesh.io import from_meshpy
            mesh = from_meshpy(mesh_info, order=1)
            dim = 2
            dt_factor = 4
        elif mesh_name.startswith("rect"):
            dim = int(mesh_name[-1:])
            mesh = mgen.generate_regular_rect_mesh(
                a=(-0.5, ) * dim,
                b=(0.5, ) * dim,
                nelements_per_axis=(mesh_par, ) * dim,
                order=4)

            if dim == 2:
                dt_factor = 4
            elif dim == 3:
                dt_factor = 2
            else:
                raise ValueError("dt_factor not known for %dd" % dim)
        elif mesh_name.startswith("warped"):
            dim = int(mesh_name[-1:])
            mesh = mgen.generate_warped_rect_mesh(dim,
                                                  order=order,
                                                  nelements_side=mesh_par)

            if dim == 2:
                dt_factor = 4
            elif dim == 3:
                dt_factor = 2
            else:
                raise ValueError("dt_factor not known for %dd" % dim)
        else:
            raise ValueError("invalid mesh name: " + mesh_name)

        v = np.array([0.27, 0.31, 0.1])[:dim]
        norm_v = la.norm(v)

        def f(x):
            return actx.np.sin(10 * x)

        def u_analytic(x, t=0):
            return f(-v.dot(x) / norm_v + t * norm_v)

        from grudge.models.advection import (StrongAdvectionOperator,
                                             WeakAdvectionOperator)
        from meshmode.mesh import BTAG_ALL

        dcoll = DiscretizationCollection(actx, mesh, order=order)
        op_class = {
            "strong": StrongAdvectionOperator,
            "weak": WeakAdvectionOperator
        }[op_type]
        adv_operator = op_class(dcoll,
                                v,
                                inflow_u=lambda t: u_analytic(
                                    thaw(dcoll.nodes(dd=BTAG_ALL), actx), t=t),
                                flux_type=flux_type)

        nodes = thaw(dcoll.nodes(), actx)
        u = u_analytic(nodes, t=0)

        def rhs(t, u):
            return adv_operator.operator(t, u)

        if dim == 3:
            final_time = 0.1
        else:
            final_time = 0.2

        from grudge.dt_utils import h_max_from_volume

        h_max = h_max_from_volume(dcoll, dim=dcoll.ambient_dim)
        dt = dt_factor * h_max / order**2
        nsteps = (final_time // dt) + 1
        dt = final_time / nsteps + 1e-15

        from grudge.shortcuts import set_up_rk4
        dt_stepper = set_up_rk4("u", dt, u, rhs)

        last_u = None

        from grudge.shortcuts import make_visualizer
        vis = make_visualizer(dcoll)

        step = 0

        for event in dt_stepper.run(t_end=final_time):
            if isinstance(event, dt_stepper.StateComputed):
                step += 1
                logger.debug("[%04d] t = %.5f", step, event.t)

                last_t = event.t
                last_u = event.state_component

                if visualize:
                    vis.write_vtk_file("fld-%s-%04d.vtu" % (mesh_par, step),
                                       [("u", event.state_component)])

        error_l2 = op.norm(dcoll, last_u - u_analytic(nodes, t=last_t), 2)
        logger.info("h_max %.5e error %.5e", h_max, error_l2)
        eoc_rec.add_data_point(h_max, actx.to_numpy(error_l2))

    logger.info(
        "\n%s", eoc_rec.pretty_print(abscissa_label="h",
                                     error_label="L2 Error"))

    if mesh_name.startswith("warped"):
        # NOTE: curvilinear meshes are hard
        assert eoc_rec.order_estimate() > order - 0.5
    else:
        assert eoc_rec.order_estimate() > order
Example #43
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 grudge.mesh import make_conformal_mesh
    return make_conformal_mesh(mesh.points, mesh.elements, bdry_tagger)
Example #44
0
def main():
    import numpy

    # from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import GeometryBuilder, Marker, generate_extrusion, make_box

    from meshpy.naca import get_naca_points

    geob = GeometryBuilder()

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

    geob.add_geometry(*generate_extrusion(
        rz_points=rz_points,
        base_shape=get_naca_points("0012", verbose=False, number_of_points=20),
        ring_markers=(wing_subdiv * 2 + 4) * [box_marker],
    ))

    from meshpy.tools import make_swizzle_matrix

    swizzle_matrix = make_swizzle_matrix("z:x,y:y,x:z")
    geob.apply_transform(lambda p: numpy.dot(swizzle_matrix, p))

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

    geob.apply_transform(deform_wing)

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

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

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

    mesh = build(mesh_info)
    print("%d elements" % len(mesh.elements))
    mesh.write_vtk("airfoil3d.vtk")
Example #45
0
def main():
    import numpy
    #from math import pi, cos, sin
    from meshpy.tet import MeshInfo, build
    from meshpy.geometry import GeometryBuilder, Marker, \
            generate_extrusion, make_box

    from meshpy.naca import get_naca_points

    geob = GeometryBuilder()

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

    geob.add_geometry(*generate_extrusion(
        rz_points=rz_points,
        base_shape=get_naca_points("0012", verbose=False, number_of_points=20),
        ring_markers=(wing_subdiv*2+4)*[box_marker]))

    from meshpy.tools import make_swizzle_matrix
    swizzle_matrix = make_swizzle_matrix("z:x,y:y,x:z")
    geob.apply_transform(lambda p: numpy.dot(swizzle_matrix, p))

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

    geob.apply_transform(deform_wing)

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

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

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

    mesh = build(mesh_info)
    print("%d elements" % len(mesh.elements))
    mesh.write_vtk("airfoil3d.vtk")
Example #46
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)
Example #47
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 grudge.mesh import make_conformal_mesh_ext
    vertices = numpy.asarray(mesh.points, dtype=float, order="C")
    from grudge.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)
Example #48
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)
Example #49
0
File: naca.py Project: gimac/hedge
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")]
    )