def test_i64(): filenames1 = ["cdbin", "rdbin", "csbin", "rsbin"] filenames2 = ["cd", "rd", "cs", "rs"] for f1, f2 in zip(filenames1, filenames2): dct1 = op4.load("tests/nastran_op4_data/" + f1 + ".op4") dct2 = op4.load("tests/nastran_op4_data/" + f2 + ".op4") assert set(dct1.keys()) == set(dct2.keys()) for nm in dct1: for j in range(2): assert np.allclose(dct1[nm][j], dct2[nm][j])
def test_wtop4_bigmat_ascii_2(): filenames = glob("tests/nastran_op4_data/*.op4") + glob( "tests/nastran_op4_data/*.op4.other") for name in filenames[:1]: if name.find("badname") != -1: continue data = op4.load(name, into="list") op4.write("temp.op4", data[0], data[1], sparse="bigmat", binary=False) data2 = op4.load("temp.op4", into="list") assert data[0] == data2[0] for d1, d2 in zip(data[1], data2[1]): assert np.all(d1 == d2) os.remove("temp.op4")
def test_rdop2mats(): dct2 = op4.load("tests/nastran_op4_data/r_c_rc.op4") dr = "tests/nastran_op2_data/" for cut in (0, 30000): for name in ("double_le.op2", "double_be.op2"): with op2.OP2(dr + name) as o2: o2._rowsCutoff = cut dct = o2.rdop2mats() assert np.allclose(dct2["rmat"][0], dct["ZUZR01"]) assert np.allclose(dct2["cmat"][0], dct["ZUZR02"]) assert np.allclose(dct2["rcmat"][0], dct["ZUZR03"]) for name in ("single_le.op2", "single_be.op2"): with op2.OP2(dr + name) as o2: o2._rowsCutoff = cut dct = o2.rdop2mats() assert np.allclose(dct2["rmat"][0], dct["ZUZR04"]) assert np.allclose(dct2["cmat"][0], dct["ZUZR05"]) assert np.allclose(dct2["rcmat"][0], dct["ZUZR06"]) with op2.OP2(dr + "double_le.op2") as o2: dct = o2.rdop2mats(["zuzr01", "zuzr03"]) assert np.allclose(dct2["rmat"][0], dct["ZUZR01"]) assert np.allclose(dct2["rcmat"][0], dct["ZUZR03"]) assert len(dct) == 2 dct = op2.rdmats(dr + "double_le.op2", ["zuzr01", "zuzr03"]) assert np.allclose(dct2["rmat"][0], dct["ZUZR01"]) assert np.allclose(dct2["rcmat"][0], dct["ZUZR03"]) assert len(dct) == 2 with op2.OP2(dr + "double_le.op2") as o2: d, l, starts, stops, headers = o2.directory() assert sorted(d.keys()) == ["CASECC", "ZUZR01", "ZUZR02", "ZUZR03"]
def test_wtop4_2(): matfile = "tests/nastran_op4_data/r_c_rc.mat" m = matlab.loadmat(matfile) names = ["rmat", "cmat", "rcmat"] mats = [] wtdct = {} for nm in names: mats.append(m[nm]) wtdct[nm] = m[nm] # write(filename, names, matrices=None, # binary=True, digits=16, endian='') filenames = [ ["tests/nastran_op4_data/temp_ascii.op4", False, ""], ["tests/nastran_op4_data/temp_le.op4", True, "<"], ["tests/nastran_op4_data/temp_be.op4", True, ">"], ] for item in filenames: filename = item[0] binary = item[1] endian = item[2] op4.write(filename, names, mats, binary=binary, endian=endian) names2, sizes, forms, mtypes = op4.dir(filename, verbose=False) assert names2 == names dct = op4.load(filename) for nm in dct: assert np.allclose(m[nm], dct[nm][0]) op4.save(filename, wtdct, binary=binary, endian=endian) dct = op4.load(filename, into="dct") for nm in dct: assert np.allclose(m[nm], dct[nm][0]) dct = op4.read(filename) for nm in dct: assert np.allclose(m[nm], dct[nm]) op4.save(filename, wtdct, binary=binary, endian=endian) dct = op4.read(filename, into="dct") for nm in dct: assert np.allclose(m[nm], dct[nm]) # clean up: for item in filenames: os.remove(item[0])
def test_rdpostop2(): post = op2.rdpostop2("tests/nas2cam_extseout/inboard.op2", 1, 1, 1, 1) dof = post["mats"]["ougv1"][0]["dof"] lam = post["mats"]["ougv1"][0]["lambda"] ougv1 = post["mats"]["ougv1"][0]["ougv1"] o4 = op4.load("tests/nas2cam_extseout/inboard.op4") mug1 = o4["mug1"][0] tug1 = nastran.rddtipch("tests/nas2cam_extseout/inboard.pch") tef1 = nastran.rddtipch("tests/nas2cam_extseout/inboard.pch", "TEF1") tes1 = nastran.rddtipch("tests/nas2cam_extseout/inboard.pch", "TES1") # ougv1, oef1, oes1 ... they don't have the constraint modes # or the resflex modes! How can they be useful? Anyway, this # checks the values present: # mug1 has 24 b-set ... get first 3 modes (rest are resflex): modes = mug1[:, 24:27] pv = locate.mat_intersect(tug1, dof)[0] assert np.allclose(modes[pv], ougv1) assert np.allclose(o4["mef1"][0][:, 24:27], post["mats"]["oef1"][0][0]) assert np.all(post["mats"]["oef1"][0][1][:, 0] == tef1[:, 0]) assert np.all(post["mats"]["oef1"][0][1][:, 1] == 34) pv = np.ones(15, bool) pv[5:7] = False pv[11:15] = False pv = np.hstack((pv, pv, pv)) assert np.allclose(o4["mes1"][0][:, 24:27], post["mats"]["oes1"][0][0][pv]) assert np.all(post["mats"]["oes1"][0][1][pv, 0] == tes1[:, 0]) assert np.all(post["mats"]["oes1"][0][1][:, 1] == 34) with op2.OP2("tests/nas2cam_extseout/inboard.op2") as o2: o2._rowsCutoff = 0 fpos = o2.dbnames["OUGV1"][0][0][0] o2._fileh.seek(fpos) name, trailer, dbtype = o2.rdop2nt() oug = o2._rdop2ougv1("OUGV1") assert np.all(oug["ougv1"] == ougv1) assert np.all(oug["dof"] == dof) assert np.all(oug["lambda"] == lam)
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)
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()
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)