def test_nat_freq_plate(plot=False, mode=0):
    nx = 15
    ny = 15

    a = 0.3
    b = 0.5

    # Material Lastrobe Lescalloy
    E = 203.e9  # Pa
    nu = 0.33

    rho = 7.83e3  # kg/m3
    h = 0.01  # m

    xtmp = np.linspace(0, a, nx)
    ytmp = np.linspace(0, b, ny)

    dx = xtmp[1] - xtmp[0]
    dy = ytmp[1] - ytmp[0]

    xmesh, ymesh = np.meshgrid(xtmp, ytmp)
    ncoords = np.vstack((xmesh.T.flatten(), ymesh.T.flatten())).T

    x = ncoords[:, 0]
    y = ncoords[:, 1]

    inner = np.logical_not(
        isclose(x, 0) | isclose(x, a) | isclose(y, 0) | isclose(y, b))
    np.random.seed(20)
    rdm = (-1 + 2 * np.random.rand(x[inner].shape[0]))
    np.random.seed(20)
    rdm = (-1 + 2 * np.random.rand(y[inner].shape[0]))
    x[inner] += dx * rdm * 0.45
    y[inner] += dy * rdm * 0.45

    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))
    nids_mesh = nids.reshape(nx, ny)
    n1s = nids_mesh[:-1, :-1].flatten()
    n2s = nids_mesh[1:, :-1].flatten()
    n3s = nids_mesh[1:, 1:].flatten()
    n4s = nids_mesh[:-1, 1:].flatten()

    plate = read_isotropic(thickness=h, E=E, nu=nu, calc_scf=True)

    K = np.zeros((DOF * nx * ny, DOF * nx * ny))
    M = np.zeros((DOF * nx * ny, DOF * nx * ny))
    quads = []

    for n1, n2, n3, n4 in zip(n1s, n2s, n3s, n4s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        pos3 = nid_pos[n3]
        pos4 = nid_pos[n4]
        r1 = ncoords[pos1]
        r2 = ncoords[pos2]
        r3 = ncoords[pos3]
        r4 = ncoords[pos4]
        normal = np.cross(r2 - r1, r3 - r2)
        assert normal > 0  # guaranteeing that all elements have CCW positive normal
        quad = Quad4R()
        quad.rho = rho
        quad.n1 = n1
        quad.n2 = n2
        quad.n3 = n3
        quad.n4 = n4
        quad.scf13 = plate.scf_k13
        quad.scf23 = plate.scf_k23
        quad.h = h
        quad.ABDE = plate.ABDE
        update_K(quad, nid_pos, ncoords, K)
        update_M(quad, nid_pos, ncoords, M)
        quads.append(quad)

    print('elements created')

    # applying boundary conditions
    # simply supported
    bk = np.zeros(K.shape[0], dtype=bool)  #array to store known DOFs
    check = isclose(x, 0.) | isclose(x, a) | isclose(y, 0) | isclose(y, b)
    bk[2::DOF] = check

    #eliminating all u,v displacements
    bk[0::DOF] = True
    bk[1::DOF] = True

    bu = ~bk  # same as np.logical_not, defining unknown DOFs

    # sub-matrices corresponding to unknown DOFs
    Kuu = K[bu, :][:, bu]
    Muu = M[bu, :][:, bu]

    eigvals, U = eigh(a=Kuu, b=Muu)
    omegan = eigvals**0.5

    # vector u containing displacements for all DOFs
    u = np.zeros(K.shape[0], dtype=float)
    u[bu] = U[:, mode]

    # theoretical reference
    m = 1
    n = 1
    D = 2 * h**3 * E / (3 * (1 - nu**2))
    wmn = (m**2 / a**2 + n**2 / b**2) * np.sqrt(D * np.pi**4 /
                                                (2 * rho * h)) / 2

    print('Theoretical omega123', wmn)
    print('Numerical omega123', omegan[0:10])

    if plot:
        import matplotlib
        matplotlib.use('TkAgg')
        import matplotlib.pyplot as plt

        plt.clf()
        for n1, n2, n3, n4 in zip(n1s, n2s, n3s, n4s):
            pos1 = nid_pos[n1]
            pos2 = nid_pos[n2]
            pos3 = nid_pos[n3]
            pos4 = nid_pos[n4]
            r1 = ncoords[pos1]
            r2 = ncoords[pos2]
            r3 = ncoords[pos3]
            r4 = ncoords[pos4]
            plt.plot([r1[0], r2[0]], [r1[1], r2[1]], 'k-')
            plt.plot([r2[0], r3[0]], [r2[1], r3[1]], 'k-')
            plt.plot([r3[0], r4[0]], [r3[1], r4[1]], 'k-')
            plt.plot([r4[0], r1[0]], [r4[1], r1[1]], 'k-')
        plt.contourf(xmesh, ymesh, u[2::DOF].reshape(xmesh.shape))
        plt.show()

    assert np.isclose(wmn, omegan[0], rtol=0.05)
Exemplo n.º 2
0
    if plot:
        import matplotlib
        matplotlib.use('TkAgg')
        import matplotlib.pyplot as plt
        plt.clf()
        ax = plt.gca()
        ax.set_aspect('equal')
        for s in ax.spines.values():
            s.set_visible(False)
        ax.set_xticks([])
        ax.set_yticks([])
        plt.triplot(ncoords[:, 0], ncoords[:, 1], d.simplices, lw=0.5)
        plt.plot(ncoords[:, 0], ncoords[:, 1], 'o', ms=2)
        plt.show()

    plate = read_isotropic(thickness=h, E=E, nu=nu, calc_scf=True)
    print('scf', plate.scf_k13, plate.scf_k23)

    K = np.zeros((DOF * nx * ny, DOF * nx * ny))
    M = np.zeros((DOF * nx * ny, DOF * nx * ny))
    trias = []
    for s in d.simplices:
        n1, n2, n3 = nids[s]
        n1, n2, n3 = n2, n3, n1
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        pos3 = nid_pos[n3]
        r1 = ncoords[pos1]
        r2 = ncoords[pos2]
        r3 = ncoords[pos3]
        normal = np.cross(r2 - r1, r3 - r2)
Exemplo n.º 3
0
def test_static_plate_quad_point_load(plot=False):
    nx = 7
    ny = 7

    # geometry
    a = 3
    b = 7
    h = 0.005  # m

    # material
    E = 200e9
    nu = 0.3

    plate = read_isotropic(thickness=h, E=E, nu=nu, calc_scf=True)

    xtmp = np.linspace(0, a, nx)
    ytmp = np.linspace(0, b, ny)
    xmesh, ymesh = np.meshgrid(xtmp, ytmp)
    ncoords = np.vstack((xmesh.T.flatten(), ymesh.T.flatten())).T
    x = ncoords[:, 0]
    y = ncoords[:, 1]

    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))
    nids_mesh = nids.reshape(nx, ny)
    n1s = nids_mesh[:-1, :-1].flatten()
    n2s = nids_mesh[1:, :-1].flatten()
    n3s = nids_mesh[1:, 1:].flatten()
    n4s = nids_mesh[:-1, 1:].flatten()

    # creating global stiffness matrix
    K = np.zeros((DOF * nx * ny, DOF * nx * ny))

    # creating elements and populating global stiffness
    quads = []
    for n1, n2, n3, n4 in zip(n1s, n2s, n3s, n4s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        pos3 = nid_pos[n3]
        pos4 = nid_pos[n4]
        r1 = ncoords[pos1]
        r2 = ncoords[pos2]
        r3 = ncoords[pos3]
        normal = np.cross(r2 - r1, r3 - r2)
        assert normal > 0  # guaranteeing that all elements have CCW positive normal
        quad = Quad4R()
        quad.n1 = n1
        quad.n2 = n2
        quad.n3 = n3
        quad.n4 = n4
        quad.scf13 = plate.scf_k13
        quad.scf23 = plate.scf_k23
        quad.h = h
        quad.ABDE = plate.ABDE
        update_K(quad, nid_pos, ncoords, K)
        quads.append(quad)

    print('elements created')

    # applying boundary conditions
    # simply supported
    bk = np.zeros(K.shape[0], dtype=bool)  #array to store known DOFs
    check = np.isclose(x, 0.) | np.isclose(x, a) | np.isclose(
        y, 0) | np.isclose(y, b)
    bk[2::DOF] = check

    # eliminating all u,v displacements
    bk[0::DOF] = True
    bk[1::DOF] = True

    bu = ~bk  # same as np.logical_not, defining unknown DOFs

    # external force vector for point load at center
    f = np.zeros(K.shape[0])
    fmid = 1.
    # force at center node
    check = np.isclose(x, a / 2) & np.isclose(y, b / 2)
    f[2::DOF][check] = fmid
    assert f.sum() == fmid

    # sub-matrices corresponding to unknown DOFs
    Kuu = K[bu, :][:, bu]
    fu = f[bu]

    # solving static problem
    uu = solve(Kuu, fu)

    # vector u containing displacements for all DOFs
    u = np.zeros(K.shape[0])
    u[bu] = uu

    w = u[2::DOF].reshape(nx, ny).T

    # obtained with bfsplate2d element, nx=ny=29
    wmax_ref = 6.594931610258557e-05
    assert np.isclose(wmax_ref, w.max(), rtol=0.02)
    if plot:
        import matplotlib
        matplotlib.use('TkAgg')
        import matplotlib.pyplot as plt
        plt.gca().set_aspect('equal')
        levels = np.linspace(w.min(), w.max(), 300)
        plt.contourf(xmesh, ymesh, w, levels=levels)
        plt.colorbar()
        plt.show()