# -*- coding: utf-8 -*- """ Created on Tue Sep 10 15:41:18 2013 Description: Script to parse bdf files to current nastran readable format. Also acts as converter for short-form (',') Date: Sept 10th 2013 Author: Gerry Harvey Update: 1/10/2013: Free vs Short form check Forces written out to file """ # get filename from user - hardcode for now # Later this will launch a dialog for browsing files name = "mmap" ext = ".bdf" filename = name + ext # Open new file for re-formatted BDF fileOUT = open("reformat.bdf", "w") fileOUT.close() # Open newfile for nodes and elements nodeOUT = open("nodes.txt", "w") nodeOUT.write("geom\n\tskew gcon\n") tetOUT = open("Tet.txt", "w") tetOUT.write("tet\n\tbufr 400000\n") hexOUT = open("Hex.txt", "w") hexOUT.write("hex\n\tbufr 400000\n") frcOUT = open("Force.txt", "w") # No need to close, but may help clashes when switching open mode nodeOUT.close() tetOUT.close() hexOUT.close() frcOUT.close() # read current BDF file fileIN = open (filename, "r") # Get number of lines in file - not needed num_lines = sum(1 for line in open(filename)) # Open files needed for output formats nodeOUT = open("nodes.txt", "a") fileOUT = open("reformat.bdf", "a") tetOUT = open("Tet.txt", "a") hexOUT = open("Hex.txt", "a") frcOUT = open("Force.txt", "a") # Set number of characters in columns n = 8 # Logic for parsing file while True: # Update current line lineNow = fileIN.readline() # Get X Y Z node locations from GRID if (lineNow.startswith('GRID')): # Perform 'free-form' or 'short form' check if "," in lineNow: # Create list of strings on line nodeLoc = lineNow.split(',') nitems = len(nodeLoc) else: nodeLoc = [lineNow[i:i+n] for i in range(0, len(lineNow), n)] nitems = len(nodeLoc) i = 1 for i in range(1,nitems): # Strip Whitespace from strings nodeLoc[i] = nodeLoc[i].lstrip() # Justify strings correctly for formatting nodeLoc[i] = nodeLoc[i].rjust(8) i = i+1 # extract node number, X, Y and Z loc - real numbers nodeNum = float(nodeLoc[1]); int(nodeNum) xLoc = float(nodeLoc[3]) yLoc = float(nodeLoc[4]) zLoc = float(nodeLoc[5]) # Write Out Node List nodeOUT.write('\t%s %d %f %f %f\n' \ %("gcon",nodeNum, xLoc, yLoc, zLoc) ) #Write Out GRID point in BDF Short Field label = "GRID" # can replace with nodeLoc[0] label = label.ljust(8) fileOUT.write('%.8s%.8s%.8s%.8s%.8s%.8s%.8s\n' \ %(label, nodeLoc[1], nodeLoc[2], nodeLoc[3], nodeLoc[4], nodeLoc[5], nodeLoc[6])) # Get nodes and materials for Tets elif (lineNow.startswith('CTETRA')): # Perform 'free-form' or 'short form' check if "," in lineNow: tetElm = lineNow.split(',') else: tetElm = [lineNow[i:i+n] for i in range(0, len(lineNow), n)] # Extract Node number, material and 1st 4 nodes # Note: can ignore 2nd CTETRA line - midline nodes. Can use '.readlines' in future tetNum = int(tetElm[1]) matNum = int(tetElm[2]) node1 = int(tetElm[3]) node2 = int(tetElm[4]) node3 = int(tetElm[5]) node4 = int(tetElm[6]) # Write out Element list tetOUT.write('\t%s %s %d %d %d %d\n' \ %("gcon", "mat1", node1, node2, node3, node4) ) # Write out ELEMENTS in BDF Short Form label = "CTETRA" # can replace with tetElm[0] fileOUT.write('%-8s%-8d%-8d%-8d%-8d%-8d%-8d\n' \ %(label, tetNum, matNum, node1, node2, node3, node4)) elif (lineNow.startswith('CHEXA')): # HEX elements split over 2 lines so read next line and add lineNxt = fileIN.readline() # Perform 'free-form' or 'short form' check if "," in lineNow: hexElm = lineNow.split(',') + lineNxt.split(',') else: hexElm = [lineNow[i:i+n] for i in range(0, len(lineNow), n)] \ + [lineNxt[i:i+n] for i in range(0, len(lineNxt), n)] # Extract Node number, material and 1st 8 nodes hexNum = int(hexElm[1]) matNum = int(hexElm[2]) node1 = int(hexElm[3]) node2 = int(hexElm[4]) node3 = int(hexElm[5]) node4 = int(hexElm[6]) node5 = int(hexElm[7]) node6 = int(hexElm[8]) node7 = int(hexElm[10]) node8 = int(hexElm[11]) # Write out Element list hexOUT.write('\t%s %s %d %d %d %d %d %d %d %d\n' \ %("gcon", "mat1", node1, node2, node3, node4, node5, node6, node7, node8) ) # Write out ELEMENTS in BDF Short Form # will have to split two lines to be formatted correctly label = "CHEXA" fileOUT.write('%-8s%-8d%-8d%-8d%-8d%-8d%-8d%-8d%-8d\n%-8s%-8d%-8d\n' \ %(label, hexNum, matNum, node1, node2, node3, node4, node5, node6, "", node7, node8)) elif (lineNow.startswith('CPENTA')): # HEX elements split over 2 lines so read next line and add lineNxt = fileIN.readline() # Perform 'free-form' or 'short form' check if "," in lineNow: hexElm = lineNow.split(',') + lineNxt.split(',') else: hexElm = [lineNow[i:i+n] for i in range(0, len(lineNow), n)] \ + [lineNxt[i:i+n] for i in range(0, len(lineNxt), n)] # Extract Node number, material and 1st 8 nodes hexNum = int(hexElm[1]) matNum = int(hexElm[2]) node1 = int(hexElm[3]) node2 = int(hexElm[4]) node3 = int(hexElm[5]) node4 = int(hexElm[5]) node5 = int(hexElm[6]) node6 = int(hexElm[7]) node7 = int(hexElm[8]) node8 = int(hexElm[8]) """ will need logic to find out which point is would be shared for the degenerate HEX element """ # Write out Element list hexOUT.write('\t%s %s %d %d %d %d %d %d %d %d\n' \ %("gcon", "mat1", node1, node2, node3, node4, node5, node6, node7, node8) ) # Write out ELEMENTS in BDF Short Form - split into 2 lines label = "CHEXA" fileOUT.write('%-8s%-8d%-8d%-8d%-8d%-8d%-8d%-8d%-8d\n%-8s%-8d%-8d\n' \ %(label, hexNum, matNum, node1, node2, node3, node4, node5, node6, "", node7, node8)) elif(lineNow.startswith('FORCE')): # Perform 'free-form' or 'short form' check if "," in lineNow: Forces = lineNow.split(',') else: Forces = [lineNow[i:i+n] for i in range(0, len(lineNow), n)] # Grab Node number from List and write to 'Forces' file ForceNode = int(Forces[2]) frcOUT.write("\t%s %d\n" %("gcon", ForceNode)) if not lineNow: break #EOF # while loops end - Write ENDDATA to reformat.bdf and close all fileOUT.write("ENDDATA") fileOUT.close() fileIN.close() fileOUT.close() nodeOUT.close() tetOUT.close() hexOUT.close() frcOUT.close()