Пример #1
0
def test_uset_convert():
    import numpy as np
    from pyyeti import cb
    from pyyeti.nastran import n2p

    # node 100 in basic is @ [50, 100, 150] inches
    uset = n2p.addgrid(None, 100, "b", 0, [50, 100, 150], 0)
    ref = (100, 100, 100)
    uset_conv, ref_conv = cb.uset_convert(uset, ref, "e2m")
    assert np.allclose(uset_conv.loc[(100, 1), "x":"z"], [1.27, 2.54, 3.81])
    assert np.allclose(ref_conv, [2.54, 2.54, 2.54])

    uset_back, ref_back = cb.uset_convert(uset_conv, ref_conv)
    assert np.allclose(uset_back, uset)
    assert np.allclose(ref_back, ref)

    uset_conv2, ref_conv = cb.uset_convert(uset_conv)
    assert np.allclose(uset, uset_conv2)
    assert ref_conv is None
Пример #2
0
def test_mk_net_drms():
    pth = os.path.dirname(inspect.getfile(cb))
    pth = os.path.join(pth, "..")
    pth = os.path.join(pth, "tests")
    pth = os.path.join(pth, "nas2cam_csuper")

    # Load the mass and stiffness from the .op4 file
    # This loads the data into a dict:
    mk = op4.load(os.path.join(pth, "inboard.op4"))
    maa = mk["mxx"][0]
    kaa = mk["kxx"][0]

    # Get the USET table The USET table has the boundary DOF
    # information (id, location, coordinate system). This is needed
    # for superelements with an indeterminate interface. The nastran
    # module has the function bulk2uset which is handy for forming the
    # USET table from bulk data.

    uset, coords = nastran.bulk2uset(os.path.join(pth, "inboard.asm"))

    # uset[::6, [0, 3, 4, 5]]
    # array([[   3.,  600.,    0.,  300.],
    #        [  11.,  600.,  300.,  300.],
    #        [  19.,  600.,  300.,    0.],
    #        [  27.,  600.,    0.,    0.]])

    # x s/c is axial (see figure in cbtf or cbcheck tutorial)
    # - make z l/v axial, but pointing down

    # z s/c  ^ y l/v
    #    \   |   / y s/c
    #       \|/
    #  <------
    # x l/v

    sccoord = [
        [900, 1, 0],
        [0, 0, 0],
        [1, 1, 0],  # z is 45 deg between x & y of l/v
        [0, 0, -1],
    ]  # x is -z l/v
    c = np.cos(45 / 180 * np.pi)
    Tl2s = np.array([[0, 0, -1.0], [-c, c, 0], [c, c, 0]])

    # Form b-set partition vector into a-set
    # In this case, we already know the b-set are first:

    n = uset.shape[0]
    b = np.arange(n)

    # array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
    #        16, 17, 18, 19, 20, 21, 22, 23])

    # convert s/c from mm, kg --> m, kg
    ref = [600, 150, 150]
    conv = (0.001, 1.0)
    g = 9.80665

    u = n2p.addgrid(None, 1, "b", sccoord, [0, 0, 0], sccoord)
    Tsc2lv = np.zeros((6, 6))
    T = u.iloc[3:, 1:]
    Tsc2lv[:3, :3] = T
    Tsc2lv[3:, 3:] = T
    assert np.allclose(Tl2s.T, Tsc2lv[:3, :3])

    net = cb.mk_net_drms(
        maa, kaa, b, uset=uset, ref=ref, sccoord=sccoord, conv=conv, g=g
    )

    usetbq, c, bset = nastran.asm2uset(os.path.join(pth, "inboard.asm"))
    with assert_raises(ValueError) as cm:
        cb.mk_net_drms(
            maa, kaa, b[:3], uset=usetbq, ref=ref, sccoord=Tl2s, conv=conv, g=g
        )
    the_msg = str(cm.exception)
    assert 0 == the_msg.find(
        f"number of rows in `uset` is {uset.shape[0]}, but must "
        f"equal len(b-set) (3)"
    )

    net2 = cb.mk_net_drms(
        maa, kaa, b, uset=usetbq, ref=ref, sccoord=Tl2s, conv=conv, g=g
    )

    # rb modes in system units:
    uset2, ref2 = cb.uset_convert(uset, ref, conv)
    rb = n2p.rbgeom_uset(uset2, ref2)
    l_sc = net.ifltma_sc[:, :n] @ rb
    l_lv = net.ifltma_lv[:, :n] @ rb
    l_scd = net.ifltmd_sc[:, :n] @ rb
    l_lvd = net.ifltmd_lv[:, :n] @ rb
    a_sc = net.ifatm_sc[:, :n] @ rb
    a_lv = net.ifatm_lv[:, :n] @ rb
    c_sc = net.cgatm_sc[:, :n] @ rb
    c_lv = net.cgatm_lv[:, :n] @ rb

    sbe = np.eye(6)
    sbe[:3] *= 1 / g
    assert np.allclose(a_sc, sbe)

    # calc what the interface forces should be:
    # - acceleration = 1 m/s**2 = 1000 mm/s**2
    # - the forces should be very similar to the 6x6 mass
    #   matrix at the reference point ... which, conveniently,
    #   is provided in the cbtf tutorial:
    mass = np.array(
        [
            [1.755, 0.0, -0.0, 0.0, 0.0, 0.0],
            [0.0, 1.755, -0.0, -0.0, 0.0, 772.22],
            [-0.0, -0.0, 1.755, 0.0, -772.22, -0.0],
            [0.0, -0.0, 0.0, 35905.202, -0.0, -0.0],
            [0.0, 0.0, -772.22, -0.0, 707976.725, 109.558],
            [0.0, 772.22, -0.0, -0.0, 109.558, 707976.725],
        ]
    )
    sbe = mass
    sbe[:, :3] *= 1000  # scale up translations
    assert abs(sbe - l_sc).max() < 0.5

    assert np.allclose(Tsc2lv @ a_sc, a_lv)
    assert np.allclose(Tsc2lv @ c_sc, c_lv)
    assert abs(l_scd).max() < 1e-6 * abs(l_sc).max()
    assert abs(l_lvd).max() < 1e-6 * abs(l_lv).max()
    scale = np.array([[1000], [1000], [1000], [1000000], [1000000], [1000000]])
    assert np.allclose((1 / scale) * (Tsc2lv @ l_sc), l_lv)

    # height and mass values from cbcheck tutorial (and then refined):
    m_kg = 1.75505183
    h_m = 1.039998351 - 0.6
    assert abs(net.height_lv - h_m) < 0.000001
    assert abs(net.weight_lv - m_kg * g) < 0.000001
    assert abs(net.height_sc - 1000 * h_m) < 0.000001 * 1000
    assert abs(net.weight_sc - 1000 * m_kg * g) < 0.000001 * 1000
    assert net.scaxial_sc == 0
    assert net.scaxial_lv == 2

    compare_nets(net, net2)

    # check the natural unit output:
    net3 = cb.mk_net_drms(
        maa, kaa, b, uset=uset, ref=ref, sccoord=Tl2s, conv=conv, g=g, tau=("mm", "m")
    )
    for drm in ("ifatm", "cgatm"):
        if drm == "ifatm":
            # only ifatm has 12 rows
            drm1 = getattr(net, drm)
            drm3 = getattr(net3, drm)
            assert np.allclose(drm3[:3], drm1[:3] * g * 1000)
            assert np.allclose(drm3[3:6], drm1[3:6])
            assert np.allclose(drm3[6:9], drm1[6:9] * g)
            assert np.allclose(drm3[9:], drm1[9:])
        for ext, factor in (("_sc", 1000), ("_lv", 1)):
            drm1 = getattr(net, drm + ext)
            drm3 = getattr(net3, drm + ext)
            assert np.allclose(drm3[:3], drm1[:3] * g * factor)
            assert np.allclose(drm3[3:], drm1[3:])

    labels3 = [i.replace("g", "mm/s^2") for i in net.ifatm_labels[:6]] + [
        i.replace("g", "m/s^2") for i in net.ifatm_labels[6:]
    ]
    print(labels3)
    print()
    print(net3.ifatm_labels)
    assert labels3 == net3.ifatm_labels

    net4 = cb.mk_net_drms(
        maa, kaa, b, uset=uset, ref=ref, sccoord=Tl2s, conv=conv, g=g, tau=("g", "m")
    )
    for drm in ("ifatm", "cgatm"):
        if drm == "ifatm":
            # only ifatm has 12 rows
            drm1 = getattr(net, drm)
            drm3 = getattr(net3, drm)
            drm4 = getattr(net4, drm)
            assert np.allclose(drm4[:3], drm1[:3])
            assert np.allclose(drm4[3:6], drm1[3:6])
            assert np.allclose(drm4[6:9], drm3[6:9])
            assert np.allclose(drm4[9:], drm3[9:])
        for ext, net_ in (("_sc", net), ("_lv", net3)):
            drm1 = getattr(net_, drm + ext)
            drm4 = getattr(net4, drm + ext)
            assert np.allclose(drm4[:3], drm1[:3])
            assert np.allclose(drm4[3:], drm1[3:])

    labels4 = net.ifatm_labels[:6] + net3.ifatm_labels[6:]
    assert labels4 == net4.ifatm_labels

    # test mixed b-set/q-set:
    na = maa.shape[0]
    q = np.r_[n:na]
    newb = np.r_[0:12, na - 12 : na]
    newq = np.r_[12 : na - 12]
    kaa_newb = np.empty((na, na))
    maa_newb = np.empty((na, na))
    for newr, oldr in [(newb, b), (newq, q)]:
        for newc, oldc in [(newb, b), (newq, q)]:
            maa_newb[np.ix_(newr, newc)] = maa[np.ix_(oldr, oldc)]
            kaa_newb[np.ix_(newr, newc)] = kaa[np.ix_(oldr, oldc)]

    net5 = cb.mk_net_drms(
        maa_newb,
        kaa_newb,
        newb,
        uset=uset,
        ref=ref,
        sccoord=sccoord,
        conv=conv,
        g=g,
        reorder=False,
    )

    assert np.allclose(net5.ifltma[:, newb], net.ifltma[:, b])
    assert np.allclose(net5.ifltma[:, newq], net.ifltma[:, q])

    net6 = cb.mk_net_drms(
        maa_newb,
        kaa_newb,
        newb,
        uset=uset,
        ref=ref,
        sccoord=sccoord,
        conv=conv,
        g=g,
        reorder=False,
        rbe3_indep_dof=123456,
    )

    assert np.allclose(net6.ifltma, net5.ifltma)
    # translations match:
    assert np.allclose(net6.ifatm_sc[:3], net5.ifatm_sc[:3])
    # rotations do not:
    assert not np.allclose(net6.ifatm_sc[3:], net5.ifatm_sc[3:])
    vec = ytools.mkpattvec([3, 4, 5], len(newb), 6).ravel()
    assert (net5.ifatm_sc[:, newb[vec]] == 0.0).all()
    assert not (net6.ifatm_sc[:, newb[vec]] == 0.0).all()