Example #1
0
def test_bulk2uset():
    xyz = np.array([[0.1, 0.2, 0.3], [1.1, 1.2, 1.3]])
    with StringIO() as f:
        nastran.wtgrids(f, [100, 200], xyz=xyz)
        u, c = nastran.bulk2uset(f)

    uset = n2p.addgrid(None, 100, "b", 0, xyz[0], 0)
    uset = n2p.addgrid(uset, 200, "b", 0, xyz[1], 0)
    assert np.allclose(uset, u)
    coord = {0: np.array([[0, 1, 0], [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]])}
    assert coord.keys() == c.keys()
    assert np.allclose(coord[0], c[0])

    blk = """
CORD2R  10      0       0.0     0.0     0.0     1.0     0.0     0.0
        0.0     1.0     0.0
"""

    with StringIO(blk) as f:
        uset, cord = nastran.bulk2uset(f)
    assert uset.size == 0
    assert len(cord) == 2
Example #2
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
Example #3
0
def test_rdcord2cards():
    cylcoord = np.array([[50, 2, 0], [0, 0, 0], [1, 0, 0], [0, 1, 0]])
    sphcoord = np.array([[51, 3, 0], [0, 0, 0], [0, 1, 0], [0, 0, 1]])

    uset = n2p.addgrid(
        None,
        [100, 200, 300],
        "b",
        [0, cylcoord, sphcoord],
        [[5, 10, 15], [32, 90, 10], [50, 90, 90]],
        [0, cylcoord, sphcoord],
    )

    with StringIO() as f:
        nastran.uset2bulk(f, uset)
        cords = nastran.rdcord2cards(f)
        u, c = nastran.bulk2uset(f)

    assert len(cords) == len(c)
    for k, v in cords.items():
        assert np.allclose(c[k], v)
Example #4
0
def test_wtrspline_rings():
    theta1 = np.arange(0, 359, 360 / 5) * np.pi / 180
    rad1 = 50.0
    sta1 = 0.0
    n1 = len(theta1)
    ring1 = np.vstack(
        (
            np.arange(1, n1 + 1),  # ID
            sta1 * np.ones(n1),  # x
            rad1 * np.cos(theta1),  # y
            rad1 * np.sin(theta1),
        )
    ).T  # z
    theta2 = np.arange(10, 359, 360 / 7) * np.pi / 180
    rad2 = 45.0
    sta2 = 1.0
    n2 = len(theta2)
    ring2 = np.vstack(
        (
            np.arange(1, n2 + 1) + 100,  # ID
            sta2 * np.ones(n2),  # x
            rad2 * np.cos(theta2),  # y
            rad2 * np.sin(theta2),
        )
    ).T  # z

    uset1 = (
        "Name 1",
        n2p.addgrid(None, ring1[:, 0].astype(int), "b", 0, ring1[:, 1:], 0),
    )
    uset2 = (
        "Name 2",
        n2p.addgrid(None, ring2[:, 0].astype(int), "b", 0, ring2[:, 1:], 0),
    )

    fig = plt.figure("rspline demo", figsize=(8, 6))
    fig.clf()
    ax = fig.add_subplot(1, 1, 1, projection="3d")

    with StringIO() as f:
        nastran.wtrspline_rings(
            f, ring1, ring2, 1001, 2001, makeplot=ax, independent="ring1"
        )
        u, c = nastran.bulk2uset(f)
        rsplines1 = nastran.rdcards(f, "RSPLINE")

    with StringIO() as f:
        nastran.wtrspline_rings(
            f, uset1, uset2, 1001, 2001, makeplot=ax, independent="n amE 2"
        )
        u2, c2 = nastran.bulk2uset(f)
        rsplines2 = nastran.rdcards(f, "RSPLINE")

    assert np.allclose(u, u2)
    for k, v in c2.items():
        assert np.allclose(c[k], v)

    # x coord of new grids should be same as ring 2 ... 1.0:
    assert np.allclose(1, u.loc[(slice(None), 1), "x"])

    # y, z coords should be like ring1, but with reduced radius to
    # match ring 2:
    assert np.allclose(ring1[:, 2:] * rad2 / rad1, u.loc[(slice(None), 1), "y":"z"])

    # the local coord:
    #  z_local is x
    #  x_local points through node 1 ... which is on y
    to_local = [[0, 1.0, 0], [0, 0, 1], [1.0, 0, 0]]
    assert np.allclose(c[10010][-3:].T, to_local)

    # rsplines1 should have the 1001 series of numbers being
    # independent:
    assert (rsplines1[:, 2] > 1000).all()

    # rsplines2 should have the 101 series of numbers being
    # independent:
    assert (rsplines2[:, 2] < 1000).all()

    assert_raises(
        ValueError,
        nastran.wtrspline_rings,
        1,
        uset1,
        uset2,
        1001,
        2001,
        makeplot="no",
        independent="badoption",
    )

    uset1 = uset1[1]
    assert_raises(
        ValueError,
        nastran.wtrspline_rings,
        1,
        uset1[:-1],
        uset2,
        1001,
        2001,
        makeplot="no",
    )

    uset3 = None
    for row in ring2:
        uset3 = n2p.addgrid(uset3, int(row[0]), "b", 0, [row[3], row[1], row[2]], 0)
    assert_raises(
        ValueError, nastran.wtrspline_rings, 1, uset1, uset3, 1001, 2001, makeplot="no"
    )
Example #5
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()