Skip to main content

Using Python to translate NASTRAN .brd inputs to APDL inputs

mark.capellaro@ansys.com | 12.16.2024

Converting data from one format to another is a perfect use of Python. Python is quite good at reading, writing and finding things in text files. This allows us to develop tools that can be used to find data in NASTRAN inputs files and create the ANSYS APDL equivalent. There might be faster tools, but for ease of creating readable code that others can use and adapt, it is hard to beat Python.

Part 1: Generate the FE model using Ansys Workbench and Mechanical

Nastran and Ansys APDL have some slightly different formats for input files but we can use python to translate inputs from NASTRAN to APDL. Using a mix of native methods and a few lines of code, we can get all the required data out of the NASTRAN input and translate that to APDL input.

For the bulk of the model data, an External Data system in Workbench can be used and then you have the model (but not the named nodal set selections). In Workbench, just import a External Data system and direct it to your NASTRAN input file. Connect that system to a Static Structural system and use Mechanical to write out the APDL input file (defaults to ds.dat). This file you can import with the finite element model of the NASTRAN input. However, any named selections in the NASTRAN input will not import.

Part 2: SETs or Named Selections in NASTRAN

Any named nodal set selections in the NASTRAN input are in the human readable .brd file in SET blocks.

SET 1 = 1,3,5,7,11,13,15,17,19,21,23,25,
        27,29,31,33,35,37,39,41,43,45,
...
        1001,1003,1005,1007,1009,1011
$HMSET  1        1 "some name"
$HMSETTYPE       1 "regular"
$Node Set: 2  Name: some other name
SET 2 = 1,...

Part 3: Finding the SET blocks start and end

To get out these SETS, a bit of creativity, patience and python is required. The original query was for large models with upwards of 200 million elements, so something reasonably efficient had to be tried.

I was testing on a limited number of nodes/elements and decided to try and find all the SET commands in the input file.

To find the close of the SET block, I just looked for lines that didn't have a comma at the end (see the sample input above, note the node number closing the block does not have a comma after it.).

So the preliminary search (later, to be optimized) finds the set start (SET) and end (no comma) and writes them to two lists, set_list and no_comma.

import time, tempfile

set_list = []
no_comma=[]
file_name = 'Mesh_0/mesh_0.bdf'
t1 = time.time()
with open(file_name,'r') as f:
    ctr = 0
    for line in f:
        if line[0:3] == 'SET':
            set_list.append(ctr)
        if line[-2:] != ',\n':
            no_comma.append(ctr)
        ctr+=1
t2 = time.time()

dt = round(t2-t1,2)
print('Time to get set data = : ' + str(dt) + ' seconds')

No comma has all lines ending without commas so it had to be corrected. This was simply done by looping through the set_list and finding the next corresponding no_comma value in the no_comma list. That values gets written to the set_end list.

# get set pairs
set_end = []
for s in set_list:
    se = [i for i in no_comma if i > s][0]
    set_end.append(se)

And for actual programmers, yes, there are probably a 1000 better ways to do this.

Part 4: Getting the SET data to a dictionary

After the start and end of the SET blocks were identified, the data has to be opened one more time to extract that data. This is written to memory as a dictionary with the dictionary keys being the names of the NASTRAN sets. This part was basically used to get the data into a useable form. Luckily the rows of data are uniform in the bdf files. Eliminating this re-open would accelerate the process, but the ability to break the code into separate parts or functions also has some advantages when debugging.

apdl_cm_data = {}    
with open(file_name,'r') as f:
    data = f.readlines()
   
    for start, end in zip(set_list,set_end):
        temp = []
        name = data[start-1].split('Name:')[-1].strip()
        print(name,start,end)
        for line_num in range(start,end+1):
            if line_num == start:
                line = data[line_num].split('=')[-1]
            else: 
                line = data[line_num]
            
            line = line.split(',')
            line = [i.strip() for i in line]
            line = [int(i) for i in line if i != '']
            temp = temp + line 
        apdl_cm_data[name] = temp

Part 5: Writing the SET data to an APDL input file

Writing the data to file for APDL read also was a bit of a challenge.

The nodes first need to be written to a parameter using the *DIM command in APDL. And there the limit of the number of values is 10, so you need to loop through the NASTRAN imported nodes in batches of 10 (or check if you have less than 10!) and use the appropriate index in the array name(n) command.

XYZ(1)=59.5,42.494,-9.01,-8.98,-8.98,9.01,-30.6,51
XYZ(9)=-51.9,14.88,10.8,-10.8

ansys apdl documentation link Then once the array parameter is complete, you loop through those nodes using the NSEL command to select them. Once the entire set is selected, you can create the component (name selection) using the CM command.

with open(r'D://cm.inp', 'w') as f:
    for key in apdl_cm_data:
        ctr=1
        data = apdl_cm_data[key]
        len_data = len(data)
        f.write('*DIM , ' + key + ', ARRAY , ' + str(len_data) + '\n')
        for sub_data in range(0,len(data),10):
            count = len_data - ctr
            if count > 10:
                count = ctr+9
            else:
                count = ctr + count - 1
            f.write(key + '(' + str(ctr) + ')=')
            [f.write(str(i)+',') for i in data[ctr:count]]
            f.write( str(data[count]) + '\n') 
            ctr+=10
            
        f.write('NSEL , S , , , ' + str(data[0]) + '\n')
        f.write('*DO , I , 2 , ' + str(len(data)) + '\n')
        f.write('NSEL , A , , , ' + key + '(I)\n')
        f.write('*ENDDO\n')
        f.write('CM , ' + key + ', NODE\n\n')

I include the APDL steps in one block because they need to be run that way. I just wrote the cm.inp file to my D drive and that can be imported in APDL (File - Read Input from...) after you have a Workbench generated APDL input file for the rest of the model.

And that is how you can get your SET selections from a .bdf file to an APDL input file.

Part 6: Putting it all together

Once you have the Ansys Workbench Mechanical created model input (Part 0 - ds.dat) and the named selections input file (here: cm.inp) you can use Ansys Classic or APDL to import the data. The native way would be use use APDL - File - Read Input from... to bring in the data.

Part 7: Conclusion

There are some situations where FE users need to be able to move from one tool to another. While Ansys has tools to do this, some details from the original NASTRAN input file might not be complete. But with a few lines of code, the rest of the data can be imported. Here the named selections data, or SET data, from a NASTRAN .brd file can be easily and efficiently translated to Ansys APDL input. The method has been successfully tested on a 200 million element model (some patience required).

For questions or improvements, please feel free to contact me via the Ansys Developer Portal or via the email at the top of the page.