Exemple #1
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()
Exemple #2
0
def test_mk_net_drms_6dof():
    # same as above, but reduced to single point interface
    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")
    mk = op4.load(os.path.join(pth, "inboard.op4"))
    maa = mk["mxx"][0]
    kaa = mk["kxx"][0]
    uset, coords = nastran.bulk2uset(os.path.join(pth, "inboard.asm"))
    n = uset.shape[0]
    b = np.arange(n)
    q = np.arange(n, maa.shape[0])
    ttl = maa.shape[0]

    # reduce to single point interface:
    rb = n2p.rbgeom_uset(uset, [600, 150, 150])

    # old = {b_24} = {rb.T @ b_6}  = [rb.T  0_6?] {b_6}
    #       {q_?}    {q_?}           [0_?6   I??] {q_?}
    trans = np.zeros((len(q) + 6, ttl))
    trans[:6, :n] = rb.T
    trans[6:, n:] = np.eye(len(q))
    maa = trans @ maa @ trans.T
    kaa = trans @ kaa @ trans.T

    # no conversion, no coordinate change:
    g = 9.80665
    n = 6
    b = np.arange(n)
    net = cb.mk_net_drms(maa, kaa, b, g=g)
    net2 = cb.mk_net_drms(maa, kaa, b, g=g, bsubset=b)
    l_sc = net.ifltma_sc[:, :n]
    l_lv = net.ifltma_lv[:, :n]
    l_scd = net.ifltmd_sc[:, :n]
    l_lvd = net.ifltmd_lv[:, :n]
    a_sc = net.ifatm_sc[:, :n]
    a_lv = net.ifatm_lv[:, :n]
    c_sc = net.cgatm_sc[:, :n]
    c_lv = net.cgatm_lv[:, :n]

    sbe = np.eye(6)
    sbe[:3] *= 1 / g
    assert np.allclose(a_sc, sbe)
    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
    assert abs(sbe - l_sc).max() < 0.0005

    Tsc2lv = np.eye(6)
    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()
    assert np.allclose((Tsc2lv @ l_sc), l_lv)

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

    compare_nets(net, net2)
Exemple #3
0
def test_cglf_moment_signs():
    pth = os.path.dirname(inspect.getfile(cb))
    pth = os.path.join(pth, "..")
    pth = os.path.join(pth, "tests")
    pth = os.path.join(pth, "cla_test_data")

    se = 101
    uset, coords = nastran.bulk2uset(os.path.join(pth, "outboard.asm"))
    dct = op4.read(os.path.join(pth, "outboard.op4"))
    maa = dct["mxx"]
    kaa = dct["kxx"]
    atm = dct["mug1"]
    ltm = dct["mef1"]
    pch = os.path.join(pth, "outboard.pch")
    atm_labels = [
        "Grid {:4d}-{:1d}".format(grid, dof) for grid, dof in nastran.rddtipch(pch)
    ]
    ltm_labels = [
        "CBAR {:4d}-{:1d}".format(cbar, arg)
        for cbar, arg in nastran.rddtipch(pch, "tef1")
    ]

    nb = uset.shape[0]
    nq = maa.shape[0] - nb
    bset = np.arange(nb)
    qset = np.arange(nq) + nb
    ref = [600.0, 150.0, 150.0]
    g = 9806.65

    # use addgrid to get coordinate transformations from lv to sc:
    cid = [1, 0, 0]
    A = [0, 0, 0]
    # define sc in terms of lv coords:
    # (all drawn out by hand)
    BC = [
        [[0, 0, 1.0], [1.0, 0, 0]],  # lv x is up
        [[0, 0, -1.0], [0, 1.0, 0]],  # lv y is up
        [[-1.0, 0, 0.0], [0, 0, 1.0]],  # lv z is up
        [[0, 0, -1.0], [-1.0, 0, 0]],  # lv x is down
        [[0, 0, 1.0], [0, -1.0, 0]],  # lv y is down
        [[0, -1.0, 0], [0, 0, -1.0]],  # lv z is down
    ]
    Ts = []
    nets = []
    rb = n2p.rbgeom_uset(uset, ref)
    rbcglfa = []
    for bc in BC:
        CI = n2p.mkusetcoordinfo([cid, A, *bc], None, {})
        T = CI[2:]
        Ts.append(T)
        net = cb.mk_net_drms(maa, kaa, bset, uset=uset, ref=ref, g=g, sccoord=T)
        nets.append(net)
        rba = net.cglfa[:, :24] @ rb
        rbcglfa.append(rba)
        # sc rows:
        assert np.all(np.sign(rba[1, [1, 5]]) == np.sign(rba[3, [1, 5]]))
        assert np.all(np.sign(rba[2, [2, 4]]) == np.sign(rba[4, [2, 4]]))
        # lv rows:
        assert np.all(np.sign(rba[6, [1, 5]]) == np.sign(rba[8, [1, 5]]))
        assert np.all(np.sign(rba[7, [2, 4]]) == np.sign(rba[9, [2, 4]]))

    wh_sc = nets[0].weight_sc * nets[0].height_sc
    wh_lv = nets[0].weight_lv * nets[0].height_lv
    n = nets[0].cgatm_sc.shape[1]
    # x is down:
    cgdrm = np.vstack(
        (
            # 5 s/c rows
            nets[0].cgatm_sc[:3],
            -nets[0].ifltma_sc[5] / wh_sc,
            nets[0].ifltma_sc[4] / wh_sc,
            # 5 l/v rows
            nets[0].cgatm_lv[:3],
            -nets[0].ifltma_lv[5] / wh_lv,
            nets[0].ifltma_lv[4] / wh_lv,
            # 4 RSS rows ... filled in during data recovery
            np.zeros((4, n)),
        )
    )
    assert np.allclose(cgdrm, nets[0].cglfa)
Exemple #4
0
        return ["{} {:4d}-{:1d}".format(lbl, g, i) for g, i in id_dof]

    atm_labels = getlabels("Grid", nastran.rddtipch(pch, "tug1"))
    #    ltm_labels = getlabels('CBAR', nastran.rddtipch(pch, 'tef1'))
    iflabels = getlabels("Grid", uset[:, :2].astype(int))

    # setup CLA parameters:
    mission = "Micro Space Station"

    nb = uset.shape[0]
    nq = maa.shape[0] - nb
    bset = np.arange(nb)
    qset = np.arange(nq) + nb
    ref = [600.0, 150.0, 150.0]
    g = 9806.65
    net = cb.mk_net_drms(maa, kaa, bset, uset=uset, ref=ref, g=g)

    # run cbcheck:
    chk = cb.cbcheck("outboard_cbcheck.out",
                     maa,
                     kaa,
                     bset,
                     bref=np.arange(6),
                     uset=uset,
                     uref=ref)

    # define some defaults for data recovery:
    defaults = dict(se=se,
                    uf_reds=(1, 1, 1.25, 1),
                    srsfrq=np.arange(0.1, 50.1, 0.1),
                    srsQs=(10, 33))