From a08feb2b2303ce6cee136bbc166b16363361d575 Mon Sep 17 00:00:00 2001 From: Tim Widrick Date: Sat, 30 Jan 2021 20:44:24 -0500 Subject: [PATCH] doc cleanup; v0.99.0 --- docs/modules/nastran/bulk.rst | 4 +- pyyeti/__init__.py | 2 +- pyyeti/cb.py | 10 +- pyyeti/cla/dr_def.py | 2 +- pyyeti/cyclecount.py | 4 +- pyyeti/nastran/n2p.py | 2 +- tests/test_nastran.py | 183 +++++++++++++++++++++++++++------- 7 files changed, 162 insertions(+), 45 deletions(-) diff --git a/docs/modules/nastran/bulk.rst b/docs/modules/nastran/bulk.rst index 80d393c..c855e91 100644 --- a/docs/modules/nastran/bulk.rst +++ b/docs/modules/nastran/bulk.rst @@ -6,6 +6,7 @@ Limited set of read/write routines for Nastran bulk data .. autosummary:: :toctree: generated/ + asm2uset bulk2uset fsearch mkcomment @@ -20,6 +21,8 @@ Limited set of read/write routines for Nastran bulk data rdextrn rdgpwg rdgrids + rdseconct + rdspoints rdtabled1 rdwtbulk uset2bulk @@ -39,5 +42,4 @@ Limited set of read/write routines for Nastran bulk data wtset wtspc1 wttabled1 - wtvcomp wtxset1 diff --git a/pyyeti/__init__.py b/pyyeti/__init__.py index e8718ba..8bdb827 100644 --- a/pyyeti/__init__.py +++ b/pyyeti/__init__.py @@ -27,4 +27,4 @@ """ -__version__ = "0.98.9" +__version__ = "0.99.0" diff --git a/pyyeti/cb.py b/pyyeti/cb.py index 0fcb015..a3cf528 100644 --- a/pyyeti/cb.py +++ b/pyyeti/cb.py @@ -929,10 +929,12 @@ def mk_net_drms( coupling run. So, why not have a `lvcoord` input instead? While that - would make more sense for this routine, `sccoord` is used - simply because that's very likely what is used in the - Nastran coupling run, making it more convenient and less - error-prone than defining a `lvcoord` input. + would likely make more sense for this routine, `sccoord` + is used simply because that's what would be used in the + Nastran coupling run (for example, `sccoord` should match + what's in the Nastran .asm file). That fact makes having + `sccoord` more synergistic and therefore less error-prone + than defining a `lvcoord` input. conv : None or 2-element array_like or string; optional If None, no unit conversion is done; otherwise, units are diff --git a/pyyeti/cla/dr_def.py b/pyyeti/cla/dr_def.py index 5cbd2de..6197ea2 100644 --- a/pyyeti/cla/dr_def.py +++ b/pyyeti/cla/dr_def.py @@ -444,7 +444,7 @@ def add( case, the list is formed internally as: ``['Row 1', 'Row 2', ...]``. This input is used to determine number of rows being recovered. If not a list, - it is converted to a list via :func:`list`. + it is converted to a list via :class:`list`. active : string; optional If 'yes', this category will be included when the :func:`DR_Event.add` function is called to add categories diff --git a/pyyeti/cyclecount.py b/pyyeti/cyclecount.py index 97afd35..2b03da5 100644 --- a/pyyeti/cyclecount.py +++ b/pyyeti/cyclecount.py @@ -125,14 +125,14 @@ def rainflow(peaks, getoffsets=False, use_pandas=True): [ 4.5, 0.5, 0.5], [ 4. , 0. , 0.5], [ 3. , 1. , 0.5]]) - >>> os + >>> os # doctest: +ELLIPSIS array([[0, 1], [1, 2], [4, 5], [2, 3], [3, 6], [6, 7], - [7, 8]]) + [7, 8]]...) """ if getoffsets: rf, os = rain.rainflow(peaks, getoffsets) diff --git a/pyyeti/nastran/n2p.py b/pyyeti/nastran/n2p.py index 8d3fb89..e081397 100644 --- a/pyyeti/nastran/n2p.py +++ b/pyyeti/nastran/n2p.py @@ -2709,7 +2709,7 @@ def addgrid(uset, gid, nasset, coordin, xyz, coordout, coordref=None): def _solve(a, b): """This is :func:`scipy.linalg.solve` but with a matrix condition - check on `a`. Call by :func:`formrbe3`.""" + check on `a`. Called by :func:`formrbe3`.""" c = np.linalg.cond(a) if c > 1 / np.finfo(float).eps: warnings.warn( diff --git a/tests/test_nastran.py b/tests/test_nastran.py index 1250846..0bff3ed 100644 --- a/tests/test_nastran.py +++ b/tests/test_nastran.py @@ -306,6 +306,124 @@ def test_uset2bulk(): # T = n2p.build_coords([10, 1, 0, *new_cs_in_basic.ravel()])[10][2:] +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 (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 (bset2 == n2p.mksetpv(uset2, "a", "b")).all() + + assert len(cords2) == len(cord2) + for k, v in cords2.items(): + assert np.allclose(cord2[k], v) + + 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]]) @@ -396,40 +514,35 @@ def test_wtextseout(): baa[q, q] = 2 * 0.05 * np.sqrt(kaa[q, q]) name = "_wtextseout_test_" pre = "tests/nas2cam_csuper/yeti_outputs/se101y" - for bh, nm in zip((True, False), ("_bh", "")): - try: - nastran.wtextseout( - name, - se=101, - maa=maa, - kaa=kaa, - baa=baa, - bset=b, - uset=usetb, - spoint1=9900101, - bh=bh, - ) - names, mats, f, t = op4.load(name + ".op4", into="list") - namesy, matsy, fy, ty = op4.load(pre + nm + ".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) - if bh: - lst = (".asm", ".pch", ".baa_dmig") - else: - lst = (".asm", ".pch") - for ext in lst: - with open(name + ext) as f: - s = f.read() - with open(pre + nm + 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) + 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) @@ -461,7 +574,7 @@ def test_wtextseout(): for ext in lst: with open(name + ext) as f: s = f.read() - with open(pre + nm + ext) as f: + with open(pre + ext) as f: sy = f.read() assert s.replace(name.upper(), "SE101") == sy