K = np.zeros((DOF * nx, DOF * nx))
M = np.zeros((DOF * nx, DOF * nx))

elems = []
# creating beam elements
nids = list(nid_pos.keys())
for n1, n2 in zip(nids[:-1], nids[1:]):
    elem = Beam2D()
    elem.n1 = n1
    elem.n2 = n2
    elem.E = E
    elem.A1 = elem.A2 = A
    elem.Izz1 = elem.Izz2 = Izz
    elem.rho = rho
    elem.interpolation = 'legendre'
    update_K(elem, nid_pos, ncoords, K)
    update_M(elem, nid_pos, M, lumped=lumped)
    elems.append(elem)

if lumped:
    assert np.count_nonzero(M - np.diag(np.diagonal(M))) == 0

# applying boundary conditions
bk = np.zeros(K.shape[0], dtype=bool)  # defining known DOFs
check = np.isclose(x, 0.)
bk[0::DOF] = check
bk[1::DOF] = check
bk[2::DOF] = check
bu = ~bk  # defining unknown DOFs

# sub-matrices corresponding to unknown DOFs
Esempio n. 2
0
def test_beam2d_displ(plot=False):
    # number of nodes
    n = 2
    # Material Lastrobe Lescalloy
    E = 203.e9  # Pa
    F = -7000
    rho = 7.83e3  # kg/m3

    L = 3
    x = np.linspace(0, L, n)
    y = np.zeros_like(x)

    # tapered properties
    b_root = 0.05  # m
    b_tip = b_root  # m
    h_root = 0.05  # m
    h_tip = h_root  # m
    A_root = h_root * b_root
    A_tip = h_tip * b_tip
    Izz_root = b_root * h_root**3 / 12
    Izz_tip = b_tip * h_tip**3 / 12

    # getting nodes
    ncoords = np.vstack((x, y)).T
    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))

    n1s = nids[0:-1]
    n2s = nids[1:]

    K = np.zeros((3 * n, 3 * n))
    M = np.zeros((3 * n, 3 * n))
    beams = []
    for n1, n2 in zip(n1s, n2s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        x1, y1 = ncoords[pos1]
        x2, y2 = ncoords[pos2]
        A1 = A2 = A_root
        Izz1 = Izz2 = Izz_root
        beam = Beam2D()
        beam.interpolation = 'legendre'
        beam.n1 = n1
        beam.n2 = n2
        # Material Lastrobe Lescalloy
        beam.E = E
        beam.rho = rho
        beam.A1, beam.A2 = A1, A2
        beam.Izz1, beam.Izz2 = Izz1, Izz2
        update_K(beam, nid_pos, ncoords, K)
        update_M(beam, nid_pos, M)
        beams.append(beam)

    # applying boundary conditions
    bk = np.zeros(K.shape[0], dtype=bool)  #array to store known DOFs
    check = np.isclose(x, 0.)  # locating node at root
    # clamping at root
    for i in range(DOF):
        bk[i::DOF] = check
    bu = ~bk  # same as np.logical_not, defining unknown DOFs

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

    # test
    f = np.zeros(K.shape[0])
    f[-2] = F
    fu = f[bu]

    # solving
    uu = solve(Kuu, fu)

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

    beam = beams[0]
    nplot = 100
    xplot = np.linspace(0, L, nplot)
    yplot = np.zeros_like(xplot)
    uinterp, vinterp = uv(beam, *u[:6], n=nplot)

    assert np.allclose(vinterp[0], [
        0.00000000e+00, -9.08870216e-05, -3.62319884e-04, -8.12456281e-04,
        -1.43945391e-03, -2.24147047e-03, -3.21666364e-03, -4.36319114e-03,
        -5.67921065e-03, -7.16287987e-03, -8.81235649e-03, -1.06257982e-02,
        -1.26013627e-02, -1.47372077e-02, -1.70314909e-02, -1.94823700e-02,
        -2.20880027e-02, -2.48465466e-02, -2.77561595e-02, -3.08149990e-02,
        -3.40212230e-02, -3.73729889e-02, -4.08684547e-02, -4.45057778e-02,
        -4.82831161e-02, -5.21986273e-02, -5.62504690e-02, -6.04367989e-02,
        -6.47557747e-02, -6.92055542e-02, -7.37842949e-02, -7.84901547e-02,
        -8.33212912e-02, -8.82758621e-02, -9.33520250e-02, -9.85479378e-02,
        -1.03861758e-01, -1.09291644e-01, -1.14835752e-01, -1.20492241e-01,
        -1.26259268e-01, -1.32134991e-01, -1.38117568e-01, -1.44205156e-01,
        -1.50395913e-01, -1.56687997e-01, -1.63079565e-01, -1.69568776e-01,
        -1.76153786e-01, -1.82832754e-01, -1.89603837e-01, -1.96465193e-01,
        -2.03414980e-01, -2.10451355e-01, -2.17572476e-01, -2.24776501e-01,
        -2.32061587e-01, -2.39425892e-01, -2.46867574e-01, -2.54384790e-01,
        -2.61975699e-01, -2.69638457e-01, -2.77371223e-01, -2.85172155e-01,
        -2.93039409e-01, -3.00971144e-01, -3.08965517e-01, -3.17020687e-01,
        -3.25134810e-01, -3.33306044e-01, -3.41532548e-01, -3.49812478e-01,
        -3.58143993e-01, -3.66525251e-01, -3.74954408e-01, -3.83429623e-01,
        -3.91949053e-01, -4.00510856e-01, -4.09113189e-01, -4.17754212e-01,
        -4.26432080e-01, -4.35144952e-01, -4.43890985e-01, -4.52668338e-01,
        -4.61475168e-01, -4.70309632e-01, -4.79169888e-01, -4.88054095e-01,
        -4.96960409e-01, -5.05886988e-01, -5.14831990e-01, -5.23793574e-01,
        -5.32769895e-01, -5.41759113e-01, -5.50759384e-01, -5.59768868e-01,
        -5.68785720e-01, -5.77808099e-01, -5.86834163e-01, -5.95862069e-01
    ])

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

        plt.gca().set_aspect('equal')
        plt.plot(x, y, '-k')
        plt.plot(xplot + uinterp[0], yplot + vinterp[0], '--r')
        plt.show()
Esempio n. 3
0
    pos1 = nid_pos[n1]
    pos2 = nid_pos[n2]
    x1, y1 = ncoords[pos1]
    x2, y2 = ncoords[pos2]
    A1 = A[nid_pos[n1]]
    A2 = A[nid_pos[n2]]
    Izz1 = Izz[nid_pos[n1]]
    Izz2 = Izz[nid_pos[n2]]
    beam = Beam2D()
    beam.n1 = n1
    beam.n2 = n2
    beam.E = E
    beam.rho = rho
    beam.A1, beam.A2 = A1, A2
    beam.Izz1, beam.Izz2 = Izz1, Izz2
    update_K(beam, nid_pos, ncoords, K)
    update_M(beam, nid_pos, M, lumped=False)
    elements.append(beam)

I = np.ones_like(M)

# applying boundary conditions
# uroot = 0
# vroot = unknown
# betaroot = 0
# utip = unknown
# vtip = prescribed displacement
# betatip = unknown
known_ind = [0, 2, (K.shape[0] - 1) - 1]
bu = np.logical_not(np.in1d(np.arange(M.shape[0]), known_ind))
bk = np.in1d(np.arange(M.shape[0]), known_ind)
Esempio n. 4
0
def test_nat_freq_cantilever_beam(plot=False, mode=0):
    n = 100

    L = 3  # total size of the beam along x

    # Material Lastrobe Lescalloy
    E = 203.e9  # Pa
    rho = 7.83e3  # kg/m3

    x = np.linspace(0, L, n)
    # path
    y = np.ones_like(x)
    # tapered properties
    b = 0.05  # m
    h = 0.05  # m
    A = h * b
    Izz = b * h**3 / 12

    # getting nodes
    ncoords = np.vstack((x, y)).T
    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))

    n1s = nids[0:-1]
    n2s = nids[1:]

    K = np.zeros((3 * n, 3 * n))
    M = np.zeros((3 * n, 3 * n))
    beams = []
    for n1, n2 in zip(n1s, n2s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        x1, y1 = ncoords[pos1]
        x2, y2 = ncoords[pos2]
        A1 = A2 = A
        Izz1 = Izz2 = Izz
        beam = Beam2D()
        beam.n1 = n1
        beam.n2 = n2
        beam.E = E
        beam.rho = rho
        beam.A1, beam.A2 = A1, A2
        beam.Izz1, beam.Izz2 = Izz1, Izz2
        update_K(beam, nid_pos, ncoords, K)
        update_M(beam, nid_pos, M)
        beams.append(beam)

    # applying boundary conditions
    bk = np.zeros(K.shape[0], dtype=bool)  #array to store known DOFs
    check = np.isclose(x, 0.)  # locating node at root
    # clamping at root
    for i in range(DOF):
        bk[i::DOF] = check
    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]

    # reference answer
    alpha123 = np.array([1.875, 4.694, 7.885])
    omega123 = alpha123**2 * np.sqrt(E * Izz / (rho * A * L**4))

    print('Theoretical omega123', omega123)
    print('Numerical omega123', omegan[0:3])
    assert np.allclose(omega123, omegan[0:3], rtol=0.01)

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

        plt.plot(x, y, '-k')
        plt.plot(x + u[0::DOF], y + u[1::DOF], '--r')
        plt.show()
Esempio n. 5
0
def test_beam2d_displ(plot=False):
    # number of nodes
    n = 2
    # Material Lastrobe Lescalloy
    E = 203.e9 # Pa
    F = -7000
    rho = 7.83e3 # kg/m3

    L = 3
    x = np.linspace(0, L, n)
    y = np.zeros_like(x)

    # tapered properties
    b_root = 0.05 # m
    b_tip = b_root # m
    h_root = 0.05 # m
    h_tip = h_root # m
    A_root = h_root*b_root
    A_tip = h_tip*b_tip
    Izz_root = b_root*h_root**3/12
    Izz_tip = b_tip*h_tip**3/12

    # getting nodes
    ncoords = np.vstack((x ,y)).T
    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))

    n1s = nids[0:-1]
    n2s = nids[1:]

    K = np.zeros((3*n, 3*n))
    M = np.zeros((3*n, 3*n))
    beams = []
    for n1, n2 in zip(n1s, n2s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        x1, y1 = ncoords[pos1]
        x2, y2 = ncoords[pos2]
        A1 = A2 = A_root
        Izz1 = Izz2 = Izz_root
        beam = Beam2D()
        beam.interpolation = 'legendre'
        beam.n1 = n1
        beam.n2 = n2
        # Material Lastrobe Lescalloy
        beam.E = E
        beam.rho = rho
        beam.A1, beam.A2 = A1, A2
        beam.Izz1, beam.Izz2 = Izz1, Izz2
        update_K(beam, nid_pos, ncoords, K)
        update_M(beam, nid_pos, M)
        beams.append(beam)

    # applying boundary conditions
    bk = np.zeros(K.shape[0], dtype=bool) #array to store known DOFs
    check = np.isclose(x, 0.) # locating node at root
    # clamping at root
    for i in range(DOF):
        bk[i::DOF] = check
    bu = ~bk # same as np.logical_not, defining unknown DOFs

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

    # test
    f = np.zeros(K.shape[0])
    f[-2] = F
    fu = f[bu]

    # solving
    uu = solve(Kuu, fu)

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

    beam = beams[0]
    nplot = 10
    xplot = np.linspace(0, L, nplot)
    yplot = np.zeros_like(xplot)
    h = np.linspace(h_root, h_tip, nplot)
    exxbot = exx(-h/2, beam, *u[:6], n=nplot)
    exxtop = exx(+h/2, beam, *u[:6], n=nplot)
    ref = np.array([-0.00496552, -0.00441379, -0.00386207, -0.00331034, -0.00275862, -0.0022069,
  -0.00165517, -0.00110345, -0.00055172, 0.])
    assert np.allclose(exxbot[0], ref)
    assert np.allclose(exxtop[0], -ref)

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

        plt.plot(xplot, exxbot[0])
        plt.plot(xplot, exxtop[0])
        plt.show()
Esempio n. 6
0
def test_static_curved_beam(plot=False):
    # number of nodes
    n = 24
    # Material Lastrobe Lescalloy
    E = 203.e9  # Pa
    F = 7000

    rho = 7.83e3  # kg/m3
    thetas = np.linspace(np.pi / 2, 0, n)
    radius = 1.2
    x = radius * np.cos(thetas)
    y = -1.2 + radius * np.sin(thetas)
    # path
    print('y_tip', y[-1])

    # tapered properties
    b_root = 0.05  # m
    b_tip = b_root  # m
    h_root = 0.05  # m
    h_tip = h_root  # m
    A_root = h_root * b_root
    A_tip = h_tip * b_tip
    Izz_root = b_root * h_root**3 / 12
    Izz_tip = b_tip * h_tip**3 / 12

    # getting nodes
    ncoords = np.vstack((x, y)).T
    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))

    n1s = nids[0:-1]
    n2s = nids[1:]

    K = np.zeros((3 * n, 3 * n))
    M = np.zeros((3 * n, 3 * n))
    beams = []
    for n1, n2 in zip(n1s, n2s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        x1, y1 = ncoords[pos1]
        x2, y2 = ncoords[pos2]
        A1 = A2 = A_root
        Izz1 = Izz2 = Izz_root
        beam = Beam2D()
        beam.interpolation = 'legendre'
        beam.n1 = n1
        beam.n2 = n2
        # Material Lastrobe Lescalloy
        beam.E = E
        beam.rho = rho
        beam.A1, beam.A2 = A1, A2
        beam.Izz1, beam.Izz2 = Izz1, Izz2
        update_K(beam, nid_pos, ncoords, K)
        update_M(beam, nid_pos, M)
        beams.append(beam)

    # applying boundary conditions
    bk = np.zeros(K.shape[0], dtype=bool)  #array to store known DOFs
    check = np.isclose(x, x.min())
    # clamping curved beam at the left extremity
    for i in range(DOF):
        bk[i::DOF] = check
    bu = ~bk  # same as np.logical_not, defining unknown DOFs

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

    # test
    f = np.zeros(K.shape[0])
    f[-2] = F
    fu = f[bu]

    # solving
    uu = solve(Kuu, fu)

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

    u = u.reshape(n, -1)

    print('u_tip', u[-1])
    ref_from_Abaqus = 5.738e-2, 4.064e-2
    print('Reference from Abaqus: u_tip', ref_from_Abaqus)
    assert np.allclose(u[-1, 0:2], ref_from_Abaqus, rtol=0.01)

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

        plt.gca().set_aspect('equal')
        plt.plot(x, y, '-k')
        plt.plot(x + u[:, 0], y + u[:, 1], '--r')
        plt.show()
def test_cantilever_beam(plot=False):
    n = 100

    L = 3  # total size of the beam along x

    # Material Lastrobe Lescalloy
    E = 203.e9  # Pa
    rho = 7.83e3  # kg/m3

    x = np.linspace(0, L, n)
    # path
    y = np.ones_like(x)
    # tapered properties
    b_root = 0.05  # m
    b_tip = b_root  # m
    h_root = 0.05  # m
    h_tip = h_root  # m
    A_root = h_root * b_root
    A_tip = h_tip * b_tip
    Izz_root = b_root * h_root**3 / 12
    Izz_tip = b_tip * h_tip**3 / 12

    # getting nodes
    ncoords = np.vstack((x, y)).T
    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))

    n1s = nids[0:-1]
    n2s = nids[1:]

    K = np.zeros((3 * n, 3 * n))
    M = np.zeros((3 * n, 3 * n))
    beams = []
    for n1, n2 in zip(n1s, n2s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        x1, y1 = ncoords[pos1]
        x2, y2 = ncoords[pos2]
        A1 = A_root + (A_tip - A_root) * x1 * A_tip / (L - 0)
        A2 = A_root + (A_tip - A_root) * x2 * A_tip / (L - 0)
        Izz1 = Izz_root + (Izz_tip - Izz_root) * x1 * Izz_tip / (L - 0)
        Izz2 = Izz_root + (Izz_tip - Izz_root) * x2 * Izz_tip / (L - 0)
        beam = Beam2D()
        beam.n1 = n1
        beam.n2 = n2
        beam.E = E
        beam.rho = rho
        beam.A1, beam.A2 = A1, A2
        beam.Izz1, beam.Izz2 = Izz1, Izz2
        update_K(beam, nid_pos, ncoords, K)
        update_M(beam, nid_pos, M)
        beams.append(beam)

    # applying boundary conditions
    bk = np.zeros(K.shape[0], dtype=bool)  #array to store known DOFs
    check = np.isclose(x, 0.)  # locating node at root
    # clamping at root
    for i in range(DOF):
        bk[i::DOF] = check
    bu = ~bk  # same as np.logical_not, defining unknown DOFs

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

    # test
    Fy = 700
    f = np.zeros(K.shape[0])
    f[-2] = Fy
    fu = f[bu]

    # solving
    uu = solve(Kuu, fu)

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

    u = u.reshape(n, -1)

    a = L
    deflection = Fy * a**3 / (3 * E * Izz_root) * (1 + 3 * (L - a) / 2 * a)
    print('Theoretical deflection', deflection)
    print('Numerical deflection', u[-1, 1])
    assert np.isclose(deflection, u[-1, 1])

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

        plt.plot(x, y, '-k')
        plt.plot(x + u[:, 0], y + u[:, 1], '--r')
        plt.show()
def test_nat_freq_curved_beam():
    n = 100
    # comparing with:
    # https://www.sciencedirect.com/science/article/pii/S0168874X06000916
    # see section 5.4
    E = 206.8e9  # Pa
    rho = 7855  # kg/m3
    A = 4.071e-3
    Izz = 6.456e-6

    thetabeam = np.deg2rad(97)
    r = 2.438
    thetas = np.linspace(0, thetabeam, n)
    x = r * np.cos(thetas)
    y = r * np.sin(thetas)

    # getting nodes
    ncoords = np.vstack((x, y)).T
    nids = 1 + np.arange(ncoords.shape[0])
    nid_pos = dict(zip(nids, np.arange(len(nids))))

    n1s = nids[0:-1]
    n2s = nids[1:]

    K = np.zeros((3 * n, 3 * n))
    M = np.zeros((3 * n, 3 * n))
    beams = []
    for n1, n2 in zip(n1s, n2s):
        pos1 = nid_pos[n1]
        pos2 = nid_pos[n2]
        x1, y1 = ncoords[pos1]
        x2, y2 = ncoords[pos2]
        A1 = A2 = A
        Izz1 = Izz2 = Izz
        beam = Beam2D()
        beam.n1 = n1
        beam.n2 = n2
        beam.E = E
        beam.rho = rho
        beam.A1, beam.A2 = A1, A2
        beam.Izz1, beam.Izz2 = Izz1, Izz2
        update_K(beam, nid_pos, ncoords, K)
        update_M(beam, nid_pos, M)
        beams.append(beam)

    # applying boundary conditions
    bk = np.zeros(K.shape[0], dtype=bool)  #array to store known DOFs
    check = np.isclose(x, x.min()) | np.isclose(
        x, x.max())  # locating nodes at both ends
    # simply supporting at both ends
    bk[0::DOF] = check  # u
    bk[1::DOF] = check  # v
    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
    omega123 = [396.98, 931.22, 1797.31]
    print('Reference omega123', omega123)
    print('Numerical omega123', omegan[0:3])
    assert np.allclose(omega123, omegan[0:3], rtol=0.01)