예제 #1
0
def test_cbcheck_indeterminate_rb_norm2():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 102
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = n2p.mksetpv(uset, "a", "b")
    q = ~b
    b = np.nonzero(b)[0]

    bref = n2p.mkdofpv(usetb, "b", [[3, 12356], [19, 3]])[0]

    # write to a string:
    with StringIO() as f:
        out = cb.cbcheck(f, maa, kaa, b, bref, usetb, em_filt=2, rb_norm=True)
        s = f.getvalue()
    s = s.splitlines()

    with open("tests/nas2cam_csuper/yeti_outputs/cbcheck_yeti_102_rbnorm.out") as f:
        sy = f.read().splitlines()

    assert s[0] == "Mass matrix is symmetric."
    assert s[1] == "Warning: mass matrix is not positive definite."
    assert s[2] == "Warning: stiffness matrix is not symmetric."

    compare_cbcheck_output(s, sy)
예제 #2
0
def test_cbcheck_reorder():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = np.nonzero(n2p.mksetpv(uset, "a", "b"))[0]

    maa = cb.cbreorder(maa, b, last=True)
    kaa = cb.cbreorder(kaa, b, last=True)
    b += maa.shape[0] - len(b)

    # write to a string:
    with StringIO() as f:
        out = cb.cbcheck(f, maa, kaa, b, b[:6], usetb, em_filt=2)
        s = f.getvalue()
    s = s.splitlines()
    with open("tests/nas2cam_csuper/yeti_outputs/cbcheck_yeti_101.out") as f:
        sy = f.read().splitlines()

    assert s[0] == "Mass matrix is symmetric."
    assert s[1] == "Mass matrix is positive definite."
    assert s[2] == "Stiffness matrix is symmetric."
    compare_cbcheck_output(s, sy)
예제 #3
0
파일: test_cb.py 프로젝트: fthomass/pyyeti
def test_cbcheck_determinate():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = n2p.mksetpv(uset, "a", "b")

    q = ~b
    b = np.nonzero(b)[0]
    q = np.nonzero(q)[0]

    center = np.mean(usetb.iloc[::6, 1:], axis=0)
    rb = n2p.rbgeom_uset(usetb, center.values)

    # transform to single pt on centerline:
    # [b, q]_old = T*[b, q]_new
    #            = [[rb, 0], [0, I]] * [b, q]_new
    T = np.zeros((len(b) + len(q), 6 + len(q)))
    T[:len(b), :6] = rb
    T[len(b):, 6:] = np.eye(len(q))

    kaa = T.T @ kaa @ T
    maa = T.T @ maa @ T
    b = np.arange(6)

    # write to a string:
    with StringIO() as f:
        out = cb.cbcheck(f, maa, kaa, b, b[:6], em_filt=2)
        s = f.getvalue()

    s = s.splitlines()
    with open("tests/nas2cam_csuper/yeti_outputs/cbcheck_yeti_101_single.out"
              ) as f:
        sy = f.read().splitlines()

    assert s[0] == "Mass matrix is symmetric."
    assert s[1] == "Mass matrix is positive definite."
    assert s[2] == "Warning: stiffness matrix is not symmetric."

    j = [10]
    jy = [10]
    assert comptable(s, sy, j, jy, label="KBB =", skip=1)
    compare_cbcheck_output(s, sy)
예제 #4
0
def test_cbcoordchk2():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    kaa = kaa[pv]

    uset = nas["uset"][se]
    b = n2p.mksetpv(uset, "a", "b")
    b = np.nonzero(b)[0]

    chk0 = cb.cbcoordchk(kaa, b, b[-6:], verbose=False)
    rbmodes0 = chk0.rbmodes[b]

    # maa = cb.cbreorder(maa, b, last=True)
    kaa = cb.cbreorder(kaa, b, last=True)
    b += kaa.shape[0] - len(b)
    bref = b[-6:]

    chk1 = cb.cbcoordchk(kaa, b, bref, verbose=False)
    rbmodes1 = chk1.rbmodes[b]

    assert np.allclose(chk1.coords, chk0.coords)
    assert np.allclose(rbmodes1, rbmodes0)
    assert np.allclose(chk1.maxerr, chk0.maxerr)
    assert chk0.refpoint_chk == chk1.refpoint_chk == "pass"
    assert abs(chk0.maxerr).max() < 1e-5

    # a case where the refpoint_chk should be 'fail':
    chk2 = cb.cbcoordchk(kaa, b, [25, 26, 27, 31, 32, 33], verbose=False)
    assert chk2.refpoint_chk == "fail"
예제 #5
0
def test_calcAM():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    maa = nas["maa"][101]
    kaa = nas["kaa"][101]
    uset = nas["uset"][101]
    b = n2p.mksetpv(uset, "a", "b")
    q = ~b
    b = np.nonzero(b)[0]

    freq = np.arange(1.0, 80.0, 1.0)

    pv = np.any(maa, axis=0)
    q = q[pv]
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]
    baa = np.zeros_like(maa)
    baa[q, q] = 2 * 0.05 * np.sqrt(kaa[q, q])

    nb = len(b)
    bdrm = np.zeros((nb, maa.shape[0]))
    bdrm[:nb, :nb] = np.eye(nb)
    AM1 = frclim.calcAM((maa, baa, kaa, b), freq)
    AM2 = frclim.calcAM((maa, baa, kaa, bdrm), freq)
    assert np.allclose(AM1, AM2)
예제 #6
0
파일: test_cb.py 프로젝트: fthomass/pyyeti
def test_cbcheck_unit_convert():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = n2p.mksetpv(uset, "a", "b")

    q = ~b
    b = np.nonzero(b)[0]
    q = np.nonzero(q)[0]

    # write to a string:
    with StringIO() as f:
        out = cb.cbcheck(
            f,
            maa,
            kaa,
            b,
            b[:6],
            uset=usetb,
            em_filt=2,
            conv=[1 / 25.4, 0.005710147154735817],
            uref=[600, 150, 150],
            rb_norm=False,
        )
        s = f.getvalue()

    s = s.splitlines()
    with open("tests/nas2cam_csuper/yeti_outputs/cbcheck_yeti_101_unitconv.out"
              ) as f:
        sy = f.read().splitlines()

    assert s[0] == "Mass matrix is symmetric."
    assert s[1] == "Mass matrix is positive definite."
    assert s[2] == "Stiffness matrix is symmetric."
    compare_cbcheck_output(s, sy)
예제 #7
0
def test_wtextseout():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = n2p.mksetpv(uset, "a", "b")
    q = ~b
    b = np.nonzero(b)[0]
    baa = np.zeros_like(maa)
    baa[q, q] = 2 * 0.05 * np.sqrt(kaa[q, q])
    name = "_wtextseout_test_"
    pre = "tests/nas2cam_csuper/yeti_outputs/se101y"
    try:
        nastran.wtextseout(
            name,
            se=101,
            maa=maa,
            kaa=kaa,
            baa=baa,
            bset=b,
            uset=usetb,
            spoint1=9900101,
        )
        names, mats, f, t = op4.load(name + ".op4", into="list")
        namesy, matsy, fy, ty = op4.load(pre + ".op4", into="list")
        assert names == namesy
        assert f == fy
        assert t == ty
        for i, (m, my) in enumerate(zip(mats, matsy)):
            assert np.allclose(m, my)
        lst = (".asm", ".pch")
        for ext in lst:
            with open(name + ext) as f:
                s = f.read()
            with open(pre + ext) as f:
                sy = f.read()
            assert s.replace(name.upper(), "SE101") == sy
    finally:
        for ext in (".asm", ".pch", ".op4"):
            if os.path.exists(name + ext):
                os.remove(name + ext)

    # test the additional writing of matrices:
    mug1 = np.arange(12).reshape(3, 4)
    mef1 = 10 * mug1
    try:
        nastran.wtextseout(
            name,
            se=101,
            maa=maa,
            kaa=kaa,
            baa=baa,
            bset=b,
            uset=usetb,
            spoint1=9900101,
            mug1=mug1,
            mef1=mef1,
        )
        names, mats, f, t = op4.load(name + ".op4", into="list")
        namesy, matsy, fy, ty = op4.load(pre + ".op4", into="list")
        assert names == namesy
        for i, (m, my) in enumerate(zip(mats, matsy)):
            if names[i] in ("mug1", "mef1"):
                assert np.allclose(m, eval(names[i]))
            else:
                assert f[i] == fy[i]
                assert t[i] == ty[i]
                assert np.allclose(m, my)
        lst = (".asm", ".pch")
        for ext in lst:
            with open(name + ext) as f:
                s = f.read()
            with open(pre + ext) as f:
                sy = f.read()
            assert s.replace(name.upper(), "SE101") == sy

    finally:
        for ext in (".asm", ".pch", ".op4", ".baa_dmig"):
            if os.path.exists(name + ext):
                os.remove(name + ext)
예제 #8
0
def test_asm2uset():
    asm1 = """
$ SE101 ASSEMBLY FILE FOR RESIDUAL RUN...INCLUDE IN BULK DATA
$
SEBULK       101  EXTOP4          MANUAL                     101
SECONCT      101       0              NO
               3       3      11      11      19      19      27      27
$
$ COORDINATE SYSTEM DATA
$
$ Coordinate 10:
CORD2R*               10               0  0.00000000e+00  0.00000000e+00*
*         0.00000000e+00  1.00000000e+00  0.00000000e+00  0.00000000e+00*
*         0.00000000e+00  1.00000000e+00  0.00000000e+00
$
$ BOUNDARY GRID DATA
$
GRID*                  3               0    600.00000000      0.00000000
*           300.00000000               0
GRID*                 11               0    600.00000000    300.00000000
*           300.00000000              10
GRID*                 19               0    600.00000000    300.00000000
*             0.00000000               0
GRID*                 27               0    600.00000000      0.00000000
*             0.00000000               0
$
SECONCT      101       0              NO
         9900101    THRU 9900122 9900101    THRU 9900122
$
SPOINT   9900101    THRU 9900122
"""
    with StringIO(asm1) as f:
        uset1, cord1, bset1 = nastran.asm2uset(f)
        cords1 = nastran.rdcord2cards(f)

    # make the uset manually for testing:
    rng = range(9900101, 9900123)
    dof = [[3, 123456], [11, 123456], [19, 123456], [27, 123456]] + [
        [i, 0] for i in rng
    ]
    nasset = np.zeros(4 + 22, np.int64)
    nasset[:4] = n2p.mkusetmask("b")
    nasset[4:] = n2p.mkusetmask("q")
    xyz = np.array(
        [
            [600.0, 0.0, 300.0],
            [600.0, 300.0, 300.0],
            [600.0, 300.0, 0.0],
            [600.0, 0.0, 0.0],
        ]
        + [[0.0, 0.0, 0.0] for i in rng]
    )

    uset1_man = n2p.make_uset(dof=dof, nasset=nasset, xyz=xyz)

    # fix up grid 11 coords:
    uset1_man.loc[(11, 2), "x"] = 10
    uset1_man.loc[(11, 4):(11, 6), "x":"z"] = [
        [0.0, 0.0, 1.0],
        [1.0, 0.0, 0.0],
        [0.0, 1.0, 0.0],
    ]
    # assert uset1.equals(uset1_man)
    assert np.allclose(uset1.reset_index(), uset1_man.reset_index())
    assert (bset1 == n2p.mksetpv(uset1, "a", "b")).all()

    assert len(cords1) == len(cord1)
    for k, v in cords1.items():
        assert np.allclose(cord1[k], v)

    asm2 = """
$ SE101 ASSEMBLY FILE FOR RESIDUAL RUN...INCLUDE IN BULK DATA
$
$1111111222222223333333344444444555555556666666677777777888888889999999900000000
SEBULK       101  EXTOP4          MANUAL                     101
SECONCT      101       0              NO
               3       3     110     110      19      19      27      27
$
$ COORDINATE SYSTEM DATA
$
$ Coordinate 10:
CORD2R*               10               0  0.00000000e+00  0.00000000e+00*
*         0.00000000e+00  1.00000000e+00  0.00000000e+00  0.00000000e+00*
*         0.00000000e+00  1.00000000e+00  0.00000000e+00
$
$ BOUNDARY GRID DATA
$
GRID*                  3               0    600.00000000      0.00000000
*           300.00000000               0
GRID*                 19               0    600.00000000    300.00000000
*             0.00000000               0
GRID*                 27               0    600.00000000      0.00000000
*             0.00000000               0
$
SPOINT   110
"""

    with StringIO(asm2) as f:
        uset2, cord2, bset2 = nastran.asm2uset(f)
        cords2 = nastran.rdcord2cards(f)

    # make the uset manually for testing:
    dof = [[3, 123456], [110, 0], [19, 123456], [27, 123456]]
    nasset = np.zeros(4, np.int64)
    nasset[:] = n2p.mkusetmask("b")
    nasset[1] = n2p.mkusetmask("q")
    xyz = np.array(
        [[600.0, 0.0, 300.0], [0.0, 0.0, 0.0], [600.0, 300.0, 0.0], [600.0, 0.0, 0.0]]
    )

    uset2_man = n2p.make_uset(dof=dof, nasset=nasset, xyz=xyz)
    # assert uset2.equals(uset2_man)
    assert np.allclose(uset2.reset_index(), uset2_man.reset_index())
    assert (bset2 == n2p.mksetpv(uset2, "a", "b")).all()

    assert len(cords2) == len(cord2)
    for k, v in cords2.items():
        assert np.allclose(cord2[k], v)
예제 #9
0
def test_rbmultchk():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = n2p.mksetpv(uset, "a", "b")
    q = ~b
    b = np.nonzero(b)[0]

    grids = [[11, 123456], [45, 123456], [60, 123456]]
    drm101, dof101 = n2p.formtran(nas, 101, grids)

    # write and read a file:
    f = tempfile.NamedTemporaryFile(delete=False)
    name = f.name
    f.close()

    rb = n2p.rbgeom_uset(usetb)
    cb.rbmultchk(name, drm101, "DRM101", rb)
    with open(name) as f:
        sfile = f.read()
    os.remove(name)

    # test rbscale and unit scale:
    with StringIO() as f:
        cb.rbmultchk(f, 0.00259 * drm101, "DRM101", 100 * rb)
        s = f.getvalue()

    pos = s.find(" which is: ")
    pos2 = s[pos:].find("\n")
    assert math.isclose(float(s[pos + 10 : pos + pos2]), 100)
    s = s.splitlines()
    table, nj1 = gettable(s, 15, 0, "Absolute Maximums", 3)
    sbe = np.array(
        [
            [600, 300, 300, 0.00259],
            [600, 300, 300, 0.00259],
            [600, 300, 300, 0.00259],
            [150, -930, 150, 0.00259],
            [600, 300, 300, 0.00259],
            [150, -930, 150, 0.00259],
        ]
    )

    assert np.allclose(table[:, 1:5], sbe)

    # write to a string:
    with StringIO() as f:
        cb.rbmultchk(f, drm101, "DRM101", rb)
        s = f.getvalue()
    assert sfile == s

    # add q-set rows to rb:
    nq = np.count_nonzero(q)
    rb2 = np.vstack((rb, np.zeros((nq, 6))))
    with StringIO() as f:
        cb.rbmultchk(f, drm101, "DRM101", rb2)
        s2 = f.getvalue()
    assert s2 == s

    # check results when b-set are last:
    drm101_last = np.hstack((drm101[:, q], drm101[:, b]))
    with StringIO() as f:
        cb.rbmultchk(f, drm101_last, "DRM101", rb, bset="last")
        s2 = f.getvalue()
    assert s2 == s

    # check results when b-set are last ... using pv:
    with StringIO() as f:
        bsetpv = np.zeros((len(b) + nq), bool)
        bsetpv[-len(b) :] = True
        cb.rbmultchk(f, drm101_last, "DRM101", rb, bset=bsetpv)
        s2 = f.getvalue()
    assert s2 == s

    with StringIO() as f:
        assert_raises(
            ValueError, cb.rbmultchk, f, drm101, "asdf", rb, bset="bad string"
        )

    # trim q-set columns out of drm:
    labels = [str(i[0]) + "  " + str(i[1]) for i in dof101]
    with StringIO() as f:
        cb.rbmultchk(
            f,
            drm101[:, b],
            "DRM101",
            rb,
            drm2=drm101[:, b],
            prtnullrows=True,
            labels=labels,
        )
        s2 = f.getvalue()

    # row 16 is now all zeros ... not comparable
    drm2 = drm101.copy()
    drm2[15] = 0
    with StringIO() as f:
        cb.rbmultchk(f, drm2, "DRM101", rb, drm2=drm2, prtnullrows=True, labels=labels)
        s3 = f.getvalue()
    assert s2 == s3

    s = s.splitlines()
    with open("tests/nas2cam_csuper/yeti_outputs/rbmultchk_yeti_101.out") as f:
        sy = f.read().splitlines()

    j = [2]
    jy = [2]
    assert comptable(s, sy, j, jy, label="Extreme ", skip=3, col=11)
    assert comptable(s, sy, j, jy, label=" Row ", skip=2, col=68)
    assert comptable(s, sy, j, jy, label=" Row ", skip=2)
    assert comptable(s, sy, j, jy, label=" Row ", skip=2)
예제 #10
0
def test_cbtf():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    maa = nas["maa"][102]
    kaa = nas["kaa"][102]
    uset = nas["uset"][102]
    b = n2p.mksetpv(uset, "a", "b")
    q = ~b
    b = np.nonzero(b)[0]

    rb = n2p.rbgeom_uset(uset.iloc[b], 3)
    freq = np.arange(1.0, 80.0, 1.0)
    a = rb[:, :1]
    a2 = a.dot(np.ones((1, len(freq))))
    a3 = rb[:, 0]

    pv = np.any(maa, axis=0)
    q = q[pv]
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]
    baa1 = np.zeros_like(maa)
    baa1[q, q] = 2 * 0.05 * np.sqrt(kaa[q, q])
    baa2 = 0.1 * np.random.randn(*maa.shape)
    baa2 = baa2.dot(baa2.T)

    bb = np.ix_(b, b)

    for baa in [baa1, baa2]:
        for delq in [False, True]:
            if delq:
                m = maa[bb]
                c = baa[bb]
                k = kaa[bb]
            else:
                m = maa
                c = baa
                k = kaa

            tf = cb.cbtf(m, c, k, a, freq, b)
            tf2 = cb.cbtf(m, c, k, a2, freq, b)
            save = {}
            tf3 = cb.cbtf(m, c, k, a3, freq, b, save)
            tf4 = cb.cbtf(m, c, k, a2, freq, b, save)

            assert np.all(freq == tf.freq)
            assert np.all(freq == tf2.freq)
            assert np.all(freq == tf3.freq)
            assert np.all(freq == tf4.freq)

            assert np.allclose(tf.frc, tf2.frc)
            assert np.allclose(tf.a, tf2.a)
            assert np.allclose(tf.d, tf2.d)
            assert np.allclose(tf.v, tf2.v)

            assert np.allclose(tf.frc, tf3.frc)
            assert np.allclose(tf.a, tf3.a)
            assert np.allclose(tf.d, tf3.d)
            assert np.allclose(tf.v, tf3.v)

            assert np.allclose(tf.frc, tf4.frc)
            assert np.allclose(tf.a, tf4.a)
            assert np.allclose(tf.d, tf4.d)
            assert np.allclose(tf.v, tf4.v)

            # confirm proper solution:
            O = 2 * np.pi * freq
            velo = 1j * O * tf.d
            acce = 1j * O * velo
            f = m.dot(acce) + c.dot(velo) + k.dot(tf.d)
            assert np.allclose(acce, tf.a)
            assert np.allclose(velo, tf.v)
            assert np.allclose(f[b], tf.frc)
            if not delq:
                assert np.allclose(f[q], 0)

    assert_raises(ValueError, cb.cbtf, maa, baa1, kaa, a2[:, :3], freq, b)

    assert_raises(ValueError, cb.cbtf, maa, baa1, kaa, a2[:3, :], freq, b)
예제 #11
0
def test_cbcheck_determinate():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = n2p.mksetpv(uset, "a", "b")

    q = ~b
    b = np.nonzero(b)[0]
    q = np.nonzero(q)[0]

    center = np.mean(usetb.iloc[::6, 1:], axis=0)
    rb = n2p.rbgeom_uset(usetb, center.values)

    # transform to single pt on centerline:
    # [b, q]_old = T*[b, q]_new
    #            = [[rb, 0], [0, I]] * [b, q]_new
    T = np.zeros((len(b) + len(q), 6 + len(q)))
    T[: len(b), :6] = rb
    T[len(b) :, 6:] = np.eye(len(q))

    kaa = T.T @ kaa @ T
    maa = T.T @ maa @ T
    b = np.arange(6)

    # write to a string:
    with StringIO() as f:
        out = cb.cbcheck(f, maa, kaa, b, b[:6], em_filt=2)
        s = f.getvalue()

    s = s.splitlines()
    with open("tests/nas2cam_csuper/yeti_outputs/cbcheck_yeti_101_single.out") as f:
        sy = f.read().splitlines()

    assert s[0] == "Mass matrix is symmetric."
    assert s[1] == "Mass matrix is positive definite."
    assert s[2] == "Warning: stiffness matrix is not symmetric."

    j = [10]
    jy = [10]
    assert comptable(s, sy, j, jy, label="KBB =", skip=1)
    compare_cbcheck_output(s, sy)

    # check with no em filter:
    with StringIO() as f:
        out2 = cb.cbcheck(f, maa, kaa, b, b[:6])
        s2 = f.getvalue()
    s2 = s2.splitlines()

    s_unique = [i for i in s if i not in s2]
    # ['Printing only the modes with at least 2.0% effective mass.',
    #  'The sum includes all modes.']

    s2_unique = [i for i in s2 if i not in s]
    # ['     5          7.025        0.00    0.00    0.00    0.00    0.88    0.00',
    #  '     6          7.025        0.00    0.00    0.00    0.00    0.00    0.00',
    #  '     7         10.913        0.00    0.00    0.00    0.00    0.00    1.52',
    #  '    11         25.135        0.00    0.00    0.00    0.00    0.00    0.42',
    #  '    12         25.140        1.03    0.00    0.00    0.00    0.00    0.00',
    #  '    13         42.173        0.00    0.00    0.00    0.51    0.00    0.00',
    #  '    14         42.193        0.00    0.00    1.04    0.00    1.02    0.00',
    #  '    16         46.895        0.00    0.00    0.00    0.00    0.00    0.00',
    #  '    17         69.173        0.00    0.13    0.00    0.00    0.00    0.99']

    assert len(s2) > len(s)
    assert len(s_unique) == 2
    assert len(s2_unique) == 9
예제 #12
0
def test_cbcheck_indeterminate():
    nas = op2.rdnas2cam("tests/nas2cam_csuper/nas2cam")
    se = 101
    maa = nas["maa"][se]
    kaa = nas["kaa"][se]
    pv = np.any(maa, axis=0)
    pv = np.ix_(pv, pv)
    maa = maa[pv]
    kaa = kaa[pv]

    uset = nas["uset"][se]
    bset = n2p.mksetpv(uset, "p", "b")
    usetb = nas["uset"][se].iloc[bset]
    b = n2p.mksetpv(uset, "a", "b")
    q = ~b
    b = np.nonzero(b)[0]

    # write and read a file:
    f = tempfile.NamedTemporaryFile(delete=False)
    name = f.name
    f.close()
    # m, k, bset, rbs, rbg, rbe, usetconv = cb.cbcheck(
    out = cb.cbcheck(name, maa, kaa, b, b[:6], uset, em_filt=2)
    with open(name) as f:
        sfile = f.read()
    os.remove(name)
    assert (out.m == maa).all()
    assert (out.k == kaa).all()
    assert out.uset.equals(usetb)

    rbg = n2p.rbgeom_uset(out.uset)
    assert np.allclose(rbg, out.rbg)
    rbg_s = np.vstack((la.solve(rbg[:6].T, rbg.T).T, np.zeros((q[q].size, 6))))
    assert abs(out.rbs - rbg_s).max() < 1e-5
    assert abs(out.rbe - rbg_s).max() < 1e-5

    # write to a string:
    with StringIO() as f:
        out = cb.cbcheck(f, maa, kaa, b, b[:6], usetb, em_filt=2)
        s = f.getvalue()

    assert sfile == s
    s = s.splitlines()

    with open("tests/nas2cam_csuper/yeti_outputs/cbcheck_yeti_101.out") as f:
        sy = f.read().splitlines()

    assert s[0] == "Mass matrix is symmetric."
    assert s[1] == "Mass matrix is positive definite."
    assert s[2] == "Stiffness matrix is symmetric."

    compare_cbcheck_output(s, sy)

    with StringIO() as f:
        out = cb.cbcheck(f, maa, kaa, b, b[:6], usetb, em_filt=2, conv="e2m")
        out2 = cb.cbcheck(f, out.m, out.k, b, b[:6], out.uset, em_filt=2, conv="m2e")
        assert np.allclose(out2.uset, usetb)
        assert np.allclose(maa, out2.m)
        assert np.allclose(kaa, out2.k)

    # check for error catches:
    with StringIO() as f:
        assert_raises(
            ValueError, cb.cbcheck, f, maa, kaa, b, b[:6], usetb.iloc[:-6], em_filt=2
        )
예제 #13
0
파일: dr_event.py 프로젝트: fthomass/pyyeti
    def add(self, nas, drdefs, uf_reds=None, method="replace"):
        """
        Add data recovery definitions for an event or set of modes.

        Parameters
        ----------
        nas : dictionary
            This is the nas2cam dictionary:
            ``nas = pyyeti.nastran.op2.rdnas2cam()``. Only used if at
            least one category in `drdefs` is for an upstream
            superelement (se != 0) and has a data recovery matrix. Can
            be anything (like None) if not needed.
        drdefs : :class:`DR_Def` instance or None
            Contains the data recovery definitions for, typically, one
            superelement. See :class:`DR_Def`. If None, this routine
            does nothing.
        uf_reds : 4-element tuple or None; optional
            If not None, this is the uncertainty factors in "reds"
            order: [rigid, elastic, dynamic, static]. The values in
            `uf_reds` either replace or multiply the original values
            (see `method`). Use a value of None for a particular
            uncertainty value to retain the original value
            unmodified. This `uf_reds` option can be useful when
            uncertainty factors are event specific rather than data
            recovery category specific or you need to add in a forcing
            function uncertainty factor.

            For example, to reset the dynamic uncertainty factor to
            1.1 while leaving the other values unchanged::

                uf_reds=(None, None, 1.1, None)
                DR.add(nas, drdefs, uf_reds)

            For another example, to increase the rigid-body and
            elastic uncertainty factors by a factor of 1.05 while
            leaving the other two values unchanged::

                uf_reds=(1.05, 1.05, None, None)
                DR.add(nas, drdefs, uf_reds, method='multiply')

        method : string or function (callable); optional
            Specifies how to update the "uf_reds" settings:

              ============  ========================================
                `method`                 Description
              ============  ========================================
              'replace'     Values in `uf_reds` (that are not None)
                            replace old values.
              'multiply'    Values in `uf_reds` (that are not None)
                            multiply the old values.
               callable     Values are computed by function (or any
                            callable). The function is only called
                            for entries where `uf_reds` is not None.
                            The call is:
                            ``method(old_value, new_value)``. See
                            examples below.
              ============  ========================================

        Notes
        -----
        Typically called once for each superelement where data
        recovery is requested. The attributes `Info`, `UF_reds` and
        `Vars` are all updated on each call to this routine.

        See :class:`DR_Def` for a discussion about how the order of
        data recovery is determined. In summary: :func:`DR_Event.add`
        determines the order of :class:`DR_Def` instances, and
        :func:`DR_Def.add` determines the order of data recovery
        categories within each :class:`DR_Def` instance.
        :func:`DR_Event.set_dr_order` can be used to modify the final
        order.

        Following are some examples of providing a function for the
        `method` parameter. Note that the function is only called when
        the `uf_reds` value is not None.

        These two calls are equivalent::

            DR.add(nas, drdefs, uf_reds, 'replace')
            DR.add(nas, drdefs, uf_reds, lambda old, new: new)

        These are also equivalent::

            DR.add(nas, drdefs, uf_reds, 'multiply')
            DR.add(nas, drdefs, uf_reds, lambda old, new: old*new)

        As a final example, if you wanted to add values onto the
        previous settings instead of multiply, you could do this::

            DR.add(nas, drdefs, uf_reds, lambda old, new: old+new)

        Raises
        ------
        ValueError
            When the there are duplicate category names.
        """
        if drdefs is None:
            return

        for name, drminfo in drdefs.items():
            if name == "_vars":
                continue

            try:
                active = drminfo.active
            except AttributeError:
                active = "yes"

            if active != "yes":
                continue

            if name in self.Info:
                raise ValueError(
                    f'"{name}" data recovery category already defined')

            # variables for how to do data recovery:
            self.Info[name] = copy.copy(drdefs[name])

            # reset uf_reds if input:
            if uf_reds is not None:
                self.Info[name].uf_reds = _merge_uf_reds(
                    self.Info[name].uf_reds, uf_reds, method=method)

            # collect all sets of uncertainty factors together for the
            # apply_uf routine later:
            uf_reds_cur = self.Info[name].uf_reds
            if uf_reds_cur not in self.UF_reds:
                self.UF_reds.append(uf_reds_cur)

        se_last = -2
        # apply ULVS to all drms and put in DR:
        for se, dct in drdefs["_vars"].drms.items():
            if not dct:
                continue
            if se not in self.Vars:
                self.Vars[se] = {}
            if se not in (0, se_last):
                ulvs = nas["ulvs"][se]
                uset = nas["uset"][se]
                # Want bset partition from aset. But note that in the
                # .asm, .pch approach to SE's, it is valid in Nastran
                # to just put all b-set & q-set in a generic a-set.
                # If that's the case, find q-set by finding the
                # spoints:
                bset = n2p.mksetpv(uset, "a", "b")  # bool type
                if bset.all():
                    # manually check for q-set in the a-set:
                    aset = np.nonzero(n2p.mksetpv(uset, "p", "a"))[0]
                    dof = uset.index.get_level_values("dof")[aset]
                    qset = dof == 0  # spoints
                    bset = ~qset
                bset = np.nonzero(bset)[0]
                Lb = len(bset)
            se_last = se

            for name, mat in dct.items():
                if name in self.Vars[se]:
                    raise ValueError(f'"{name}" is already in Vars[{se}]')
                if se == 0:
                    self.Vars[se][name] = mat
                elif mat.shape[1] > Lb:
                    self.Vars[se][name] = mat @ ulvs
                else:
                    self.Vars[se][name] = mat @ ulvs[bset]

        # put all nondrms in DR:
        for se, dct in drdefs["_vars"].nondrms.items():
            if se not in self.Vars:
                self.Vars[se] = {}
            for name, mat in dct.items():
                if name in self.Vars[se]:
                    raise ValueError(f'"{name}" is already in Vars[{se}]')
                self.Vars[se][name] = mat