0

If I want to import a Nastran Deck into a Python Array, in one fell swoop using numpy. How can I go about it? Where am I going wrong?

I have a file with only Grids in it. Grids are all equally spaced with Nastran's Short translator (8 characters)

$ MH Nodes
$2345678$2345678$2345678$2345678$2345678$2345678
GRID     25601          58.50002-57.749923.05                      
GRID     25602          58.81002-57.749923.05  

using the dtype command from Numpy, is great if I understand it correctly. Here is my code:

fileMH = "Gnodes.bdf"

dtyp = np.dtype([
                ("Grid",(np.void,8)),
                ("GN",(np.int,8)),
                ("Prop",(np.void,8)),
                ("X",(np.float,8)),
                ("Y",(np.float,8)),
                ("Z",(np.float,8)),
])

f = np.loadtxt(fileMH,dtyp,comments="$")

The error I get is a float error, however I was expecting dtype to extract 8 characters at a time out of the string. Here is the error:

ValueError: invalid literal for float(): 58.50002-57.749923.05

Help is appreciated.

P.S. Can some please make a nastran tag, huge amounts of data crunching is done in nastran, that requires smart programing. It would be helpful.

Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
CromeX
  • 445
  • 1
  • 7
  • 20

2 Answers2

2

The dtype specifies the layout of the binary data in memory. It doesn't define the format of text in a file.

Your data file has fixed-width fields. That is, each field uses eight characters, and there is no special delimiter character to separate the fields. You can read such a file using numpy.genfromtxt, by specifying the field widths in the delimiter argument.

Here's an example in an ipython session. First, here's your sample file. (I edited the file to ensure that there are three spaces after the final 05 in the second and third lines, but this wasn't necessary.)

In [15]: !cat nastran_data.txt
$ MH Nodes
$2345678$2345678$2345678$2345678$2345678$2345678
GRID     25601          58.50002-57.749923.05   
GRID     25602          58.81002-57.749923.05   

Here's the data type of the array to be created by genfromtxt. Note that the GN field has type np.int64, and the X, Y and Z fields have type np.float64.

In [16]: dt = np.dtype([('Grid', 'S8'), ('GN', np.int64), ('Prop', 'S8'), ('X', np.float64), ('Y', np.float64), ('Z', np.float64)])

Read the file using genfromtxt, with six fixed-width fields, each of length 8:

In [18]: a = np.genfromtxt('nastran_data.txt', dtype=dt, delimiter=(8, 8, 8, 8, 8, 8), skip_header=2)

In [19]: a
Out[19]: 
array([('GRID    ', 25601, '        ', 58.50002, -57.7499, 23.05),
       ('GRID    ', 25602, '        ', 58.81002, -57.7499, 23.05)], 
      dtype=[('Grid', 'S8'), ('GN', '<i8'), ('Prop', 'S8'), ('X', '<f8'), ('Y', '<f8'), ('Z', '<f8')])

In [20]: a['GN']
Out[20]: array([25601, 25602])

In [21]: a['X']
Out[21]: array([ 58.50002,  58.81002])
Warren Weckesser
  • 110,654
  • 19
  • 194
  • 214
  • That's Excellent thank you.... out of curiosity, how is referencing the binary data in memory helpful? – CromeX Oct 21 '15 at 09:57
2

instead of numpy, perhaps pyNastran would work? https://github.com/SteveDoyle2/pyNastran

this examples prints nodes

import pyNastran
from pyNastran.bdf.bdf import BDF
model = BDF()
model.read_bdf('inputdeck.bdf', xref=True)
model.nodes
{1: GRID           1              8.      3.      0.,
 2: GRID           2              8.      9.      0.,
 3: GRID           3              8.     11.      0.,
 4: GRID           4              8.     13.      0.,
 5: GRID           5             -8.      3.      0.,
 6: GRID           6             -8.      9.      0.,
 7: GRID           7             -8.     11.      0.,
 8: GRID           8             -8.     13.      0.,
 9: GRID           9              2.      5.      0.}
nagordon
  • 1,307
  • 2
  • 13
  • 16