Пример #1
0
def CurvedPlate(ncirc=2, nlong=20, show_plot=False):
    """Creates custom mesh for plate with curved edges
        ncirc           discretisation around circular fillets
        nlong           discretisation along the length - X
    """

    mesh_arc = Mesh()
    mesh_arc.Arc(element_type="quad", nrad=ncirc, ncirc=ncirc, radius=5)

    mesh_arc1 = deepcopy(mesh_arc)
    mesh_arc1.points[:, 1] += 15
    mesh_arc1.points[:, 0] += 95
    mesh_arc2 = deepcopy(mesh_arc)
    mesh_arc2.points[:, 1] += 15
    mesh_arc2.points[:, 0] *= -1.
    mesh_arc2.points[:, 0] += 5.

    mesh_plate1 = Mesh()
    mesh_plate1.Rectangle(element_type="quad",
                          lower_left_point=(5, 15),
                          upper_right_point=(95, 20),
                          ny=ncirc,
                          nx=nlong)

    mesh_plate2 = deepcopy(mesh_plate1)
    mesh_plate2.points[:, 1] -= 5.

    mesh_square1 = Mesh()
    mesh_square1.Square(element_type="quad",
                        lower_left_point=(0, 10),
                        side_length=5,
                        nx=ncirc,
                        ny=ncirc)

    mesh_square2 = deepcopy(mesh_square1)
    mesh_square2.points[:, 0] += 95

    mesh = mesh_plate1 + mesh_plate2 + mesh_arc1 + mesh_arc2 + mesh_square1 + mesh_square2

    mesh.Extrude(length=0.5, nlong=1)

    mesh2 = deepcopy(mesh)
    mesh2.points[:, 2] += 0.5
    mesh += mesh2

    if show_plot:
        mesh.SimplePlot()

    return mesh
Пример #2
0
def SubdivisionCircle(center=(0., 0.),
                      radius=1.,
                      nrad=16,
                      ncirc=40,
                      element_type="tri",
                      refinement=False,
                      refinement_level=2):
    """Creates a mesh on circle using midpoint subdivision.
        This function is internally called from Mesh.Circle if
        'midpoint_subdivision' algorithm is selected
    """

    r = float(radius)
    h_r = float(radius) / 2.
    nx = int(ncirc / 4.)
    ny = int(nrad / 2.)

    if nx < 3:
        warn("Number of division in circumferential direction too low")

    mesh = Mesh()
    mesh.Rectangle(element_type="quad",
                   lower_left_point=(-1., -1.),
                   upper_right_point=(1., 1.),
                   nx=nx,
                   ny=ny)

    uv = np.array([
        [-1., -1],
        [1., -1],
        [1., 1],
        [-1., 1],
    ])

    t = np.pi / 4
    end_points = np.array([
        [-h_r * np.cos(t), h_r * np.sin(t)],
        [h_r * np.cos(t), h_r * np.sin(t)],
        [r * np.cos(t), r * np.sin(t)],
        [-r * np.cos(t), r * np.sin(t)],
    ])

    edge_points = mesh.points[np.unique(mesh.edges), :]

    new_end_points = []
    new_end_points.append(end_points[0, :])
    new_end_points.append(end_points[1, :])
    new_end_points.append(end_points[2, :])

    tt = np.linspace(np.pi / 4, 3 * np.pi / 4, nx)
    x = r * np.cos(tt)
    y = r * np.sin(tt)
    interp_p = np.vstack((x, y)).T

    for i in range(1, len(x) - 1):
        new_end_points.append([x[i], y[i]])
    new_end_points.append(end_points[3, :])
    new_end_points = np.array(new_end_points)

    new_uv = []
    new_uv.append(uv[0, :])
    new_uv.append(uv[1, :])
    new_uv.append(uv[2, :])

    L = 0.
    for i in range(1, interp_p.shape[0]):
        L += np.linalg.norm(interp_p[i, :] - interp_p[i - 1, :])

    interp_uv = []
    last_uv = uv[2, :]
    for i in range(1, interp_p.shape[0] - 1):
        val = (uv[3, :] - uv[2, :]) * np.linalg.norm(
            interp_p[i, :] - interp_p[i - 1, :]) / L + last_uv
        last_uv = np.copy(val)
        interp_uv.append(val)
    interp_uv = np.array(interp_uv)

    new_uv = np.array(new_uv)
    if interp_uv.shape[0] != 0:
        new_uv = np.vstack((new_uv, interp_uv))
    new_uv = np.vstack((new_uv, uv[3, :]))

    from Florence.FunctionSpace import MeanValueCoordinateMapping
    new_points = np.zeros_like(mesh.points)
    for i in range(mesh.nnode):
        point = MeanValueCoordinateMapping(mesh.points[i, :], new_uv,
                                           new_end_points)
        new_points[i, :] = point
    mesh.points = new_points

    rmesh = deepcopy(mesh)
    rmesh.points = mesh.Rotate(angle=np.pi / 2., copy=True)
    mesh += rmesh
    rmesh.points = rmesh.Rotate(angle=np.pi / 2., copy=True)
    mesh += rmesh
    rmesh.points = rmesh.Rotate(angle=np.pi / 2., copy=True)
    mesh += rmesh

    mesh.LaplacianSmoothing(niter=10)
    qmesh = Mesh()
    qmesh.Rectangle(element_type="quad",
                    lower_left_point=(-h_r * np.cos(t), -h_r * np.sin(t)),
                    upper_right_point=(h_r * np.cos(t), h_r * np.sin(t)),
                    nx=nx,
                    ny=nx)
    mesh += qmesh

    mesh.LaplacianSmoothing(niter=20)

    mesh.points[:, 0] += center[0]
    mesh.points[:, 1] += center[1]

    if refinement:
        mesh.Refine(level=refinement_level)

    if element_type == "tri":
        sys.stdout = open(os.devnull, "w")
        mesh.ConvertQuadsToTris()
        sys.stdout = sys.__stdout__

    return mesh
Пример #3
0
def SubdivisionArc(center=(0., 0.),
                   radius=1.,
                   nrad=16,
                   ncirc=40,
                   start_angle=0.,
                   end_angle=np.pi / 2.,
                   element_type="tri",
                   refinement=False,
                   refinement_level=2):
    """Creates a mesh on circle using midpoint subdivision.
        This function is internally called from Mesh.Circle if
        'midpoint_subdivision' algorithm is selected
    """

    if start_angle != 0. and end_angle != np.pi / 2.:
        raise ValueError(
            "Subdivision based arc only produces meshes for a quarter-circle arc for now"
        )

    r = float(radius)
    h_r = float(radius) / 2.
    nx = int(ncirc / 4.)
    ny = int(nrad / 2.)

    if nx < 3:
        warn("Number of division in circumferential direction too low")

    mesh = Mesh()
    mesh.Rectangle(element_type="quad",
                   lower_left_point=(-1., -1.),
                   upper_right_point=(1., 1.),
                   nx=nx,
                   ny=ny)

    uv = np.array([
        [-1., -1],
        [1., -1],
        [1., 1],
        [-1., 1],
    ])

    t = np.pi / 4.
    end_points = np.array([
        [0., h_r * np.sin(t)],
        [h_r * np.cos(t), h_r * np.sin(t)],
        [r * np.cos(t), r * np.sin(t)],
        [0., radius],
    ])

    edge_points = mesh.points[np.unique(mesh.edges), :]

    new_end_points = []
    new_end_points.append(end_points[0, :])
    new_end_points.append(end_points[1, :])
    new_end_points.append(end_points[2, :])

    tt = np.linspace(np.pi / 4, np.pi / 2, nx)
    x = r * np.cos(tt)
    y = r * np.sin(tt)
    interp_p = np.vstack((x, y)).T

    for i in range(1, len(x) - 1):
        new_end_points.append([x[i], y[i]])
    new_end_points.append(end_points[3, :])
    new_end_points = np.array(new_end_points)

    new_uv = []
    new_uv.append(uv[0, :])
    new_uv.append(uv[1, :])
    new_uv.append(uv[2, :])

    L = 0.
    for i in range(1, interp_p.shape[0]):
        L += np.linalg.norm(interp_p[i, :] - interp_p[i - 1, :])

    interp_uv = []
    last_uv = uv[2, :]
    for i in range(1, interp_p.shape[0] - 1):
        val = (uv[3, :] - uv[2, :]) * np.linalg.norm(
            interp_p[i, :] - interp_p[i - 1, :]) / L + last_uv
        last_uv = np.copy(val)
        interp_uv.append(val)
    interp_uv = np.array(interp_uv)

    new_uv = np.array(new_uv)
    if interp_uv.shape[0] != 0:
        new_uv = np.vstack((new_uv, interp_uv))
    new_uv = np.vstack((new_uv, uv[3, :]))

    from Florence.FunctionSpace import MeanValueCoordinateMapping
    new_points = np.zeros_like(mesh.points)
    # All nodes barring the ones lying on the arc
    for i in range(mesh.nnode - nx - 1):
        point = MeanValueCoordinateMapping(mesh.points[i, :], new_uv,
                                           new_end_points)
        new_points[i, :] = point
    # The nodes on the arc are not exactly on the arc
    # so they need to be snapped/clipped
    tt = np.linspace(np.pi / 4, np.pi / 2, nx + 1)[::-1]
    x = r * np.cos(tt)
    y = r * np.sin(tt)
    new_points[mesh.nnode - nx - 1:, :] = np.vstack((x, y)).T
    mesh.points = new_points

    rmesh = deepcopy(mesh)
    rmesh.points = mesh.Rotate(angle=-np.pi / 2., copy=True)
    rmesh.points[:, 1] *= -1.
    mesh += rmesh

    mesh.LaplacianSmoothing(niter=10)
    qmesh = Mesh()
    qmesh.Rectangle(element_type="quad",
                    lower_left_point=(0.0, 0.0),
                    upper_right_point=(h_r * np.cos(t), h_r * np.sin(t)),
                    nx=nx,
                    ny=nx)
    mesh += qmesh

    # mesh.LaplacianSmoothing(niter=20)
    NodeSliderSmootherArc(mesh, niter=20)

    mesh.points[:, 0] += center[0]
    mesh.points[:, 1] += center[1]

    if refinement:
        mesh.Refine(level=refinement_level)

    if element_type == "tri":
        sys.stdout = open(os.devnull, "w")
        mesh.ConvertQuadsToTris()
        sys.stdout = sys.__stdout__

    return mesh