pyNastran
0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
|
00001 ## GNU Lesser General Public License 00002 ## 00003 ## Program pyNastran - a python interface to NASTRAN files 00004 ## Copyright (C) 2011-2012 Steven Doyle, Al Danial 00005 ## 00006 ## Authors and copyright holders of pyNastran 00007 ## Steven Doyle <mesheb82@gmail.com> 00008 ## Al Danial <al.danial@gmail.com> 00009 ## 00010 ## This file is part of pyNastran. 00011 ## 00012 ## pyNastran is free software: you can redistribute it and/or modify 00013 ## it under the terms of the GNU Lesser General Public License as published by 00014 ## the Free Software Foundation, either version 3 of the License, or 00015 ## (at your option) any later version. 00016 ## 00017 ## pyNastran is distributed in the hope that it will be useful, 00018 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 ## GNU General Public License for more details. 00021 ## 00022 ## You should have received a copy of the GNU Lesser General Public License 00023 ## along with pyNastran. If not, see <http://www.gnu.org/licenses/>. 00024 ## 00025 00026 from __future__ import division, print_function 00027 00028 class Op2Codes(object): 00029 def ElementType(self, eCode): 00030 elements = { 00031 None : '', 00032 0 : 'GRID', 00033 1 : 'ROD', 00034 2 : 'BEAM', 00035 3 : 'TUBE', 00036 4 : 'SHEAR', 00037 5 : 'FORMON12', 00038 6 : 'FORCE', 00039 7 : 'PLOAD4', 00040 8 : 'PLOADX1', 00041 9 : 'PLOAD/PLOAD2', 00042 10 : 'CONROD', 00043 11 : 'ELAS1', 00044 12 : 'ELAS2', 00045 13 : 'ELAS3', 00046 14 : 'ELAS4', 00047 15 : 'AEROT3', 00048 16 : 'AEROBEAM', 00049 17 : None, 00050 18 : None, 00051 19 : None, 00052 20 : 'DAMP1', 00053 21 : 'DAMP2', 00054 22 : 'DAMP3', 00055 23 : 'DAMP4', 00056 24 : 'VISC', 00057 25 : 'MASS1', 00058 26 : 'MASS2', 00059 27 : 'MASS3', 00060 28 : 'MASS4', 00061 29 : 'CONM1', 00062 30 : 'CONM2', 00063 31 : 'PLOTEL', 00064 32 : None, 00065 33 : 'QUAD4', 00066 34 : 'BAR', 00067 35 : 'CON', 00068 36 : None, 00069 37 : None, 00070 38 : 'GAP', 00071 39 : 'TETRA', 00072 40 : 'BUS1D', 00073 41 : None, 00074 42 : None, 00075 43 : 'FLUID2', 00076 44 : 'FLUID3', 00077 45 : 'FLUID4', 00078 46 : 'FLMASS', 00079 47 : 'AXIF2', 00080 48 : 'AXIF3', 00081 49 : 'AXIF4', 00082 50 : 'SLOT3', 00083 51 : 'SLOT4', 00084 52 : 'HBDY', 00085 53 : 'TRIAX6', 00086 54 : None, 00087 55 : 'DUM3', 00088 56 : 'DUM4', 00089 57 : 'DUM5', 00090 58 : 'DUM6', 00091 59 : 'DUM7', 00092 60 : 'DUM8', 00093 61 : 'DUM9', 00094 62 : None, 00095 63 : None, 00096 64 : 'QUAD8', 00097 65 : None, 00098 66 : None, 00099 67 : 'HEXA', 00100 68 : 'PENTA', 00101 69 : 'BEND', 00102 70 : 'TRIAR', 00103 71 : None, 00104 72 : 'AEROQ4', 00105 73 : None, 00106 74 : 'TRIA3', 00107 75 : 'TRIA6', 00108 76 : 'HEXPR', 00109 77 : 'PENPR', 00110 78 : 'TETPR', 00111 79 : None, 00112 80 : None, 00113 81 : None, 00114 82 : 'QUADR', 00115 83 : 'HACAB', 00116 84 : 'HACBR', 00117 85 : 'TETRANL', 00118 86 : 'GAPNL', 00119 87 : 'TUBENL', 00120 88 : 'TRIA3NL', 00121 89 : 'RODNL', 00122 90 : 'QUAD4NL', 00123 91 : 'PENTANL', 00124 92 : 'CONRODNL', 00125 93 : 'HEXANL', 00126 94 : 'BEAMNL', 00127 95 : 'QUAD4LC', 00128 96 : 'QUAD8LC', 00129 97 : 'TRIA3LC', 00130 98 : 'TRIA6LC', 00131 99 : None, 00132 100 : 'BARS', 00133 101 : 'AABSF', 00134 102 : 'BUSH', 00135 103 : 'QUADP', 00136 104 : 'TRIAP', 00137 105 : 'BEAMP', 00138 106 : 'DAMP5', 00139 107 : 'CHBDYE', 00140 108 : 'CHBDYG', 00141 109 : 'CHBDYP', 00142 110 : 'CONV', 00143 111 : 'CONVM', 00144 112 : 'QBDY3', 00145 113 : 'QVECT', 00146 114 : 'QVOL', 00147 115 : 'RADBC', 00148 116 : 'SLIF1D', 00149 117 : 'WELDC', 00150 118 : 'WELDP', 00151 119 : 'GENEL', 00152 120 : 'DMIG', 00153 121 : None, 00154 122 : None, 00155 123 : None, 00156 124 : None, 00157 125 : None, 00158 126 : None, 00159 127 : None, 00160 128 : None, 00161 129 : None, 00162 130 : None, 00163 131 : None, 00164 132 : None, 00165 133 : None, 00166 134 : None, 00167 135 : None, 00168 136 : None, 00169 137 : None, 00170 138 : None, 00171 139 : 'QUAD4FD', 00172 140 : 'HEXA8FD', 00173 141 : 'HEXAP', 00174 142 : 'PENTAP', 00175 143 : 'TETRAP', 00176 144 : 'QUAD144', 00177 145 : 'VUHEXA', 00178 146 : 'VUPENTA', 00179 147 : 'VUTETRA', 00180 148 : None, 00181 149 : None, 00182 150 : None, 00183 151 : None, 00184 152 : None, 00185 153 : None, 00186 154 : None, 00187 155 : None, 00188 156 : None, 00189 157 : None, 00190 158 : None, 00191 159 : None, 00192 160 : 'PENTA6FD', 00193 161 : 'TETRA4FD', 00194 162 : 'TRIA3FD', 00195 163 : 'HEXAFD', 00196 164 : 'QUADFD', 00197 165 : 'PENTAFD', 00198 166 : 'TETRAFD', 00199 167 : 'TRIAFD', 00200 168 : 'TRIAX3FD', 00201 169 : 'TRIAXFD', 00202 170 : 'QUADX4FD', 00203 171 : 'QUADXFD', 00204 172 : 'QUADRNL', 00205 173 : 'TRIARNL', 00206 174 : None, 00207 175 : None, 00208 176 : None, 00209 177 : None, 00210 178 : None, 00211 179 : None, 00212 180 : None, 00213 181 : None, 00214 182 : None, 00215 183 : None, 00216 184 : None, 00217 185 : None, 00218 186 : None, 00219 187 : None, 00220 188 : None, 00221 189 : 'VUQUAD', 00222 190 : 'VUTRIA', 00223 191 : 'VUBEAM', 00224 192 : 'CVINT', 00225 193 : None, 00226 194 : None, 00227 195 : None, 00228 196 : None, 00229 197 : 'SFINT', 00230 198 : 'CNVPEL', 00231 199 : 'VUHBDY', 00232 200 : 'WELD', 00233 201 : 'QUAD4FD', 00234 202 : 'HEXA8FD', 00235 203 : 'SLIF1D?', 00236 204 : 'PENTA6FD', 00237 205 : 'TETRA4FD', 00238 206 : 'TRIA3FD', 00239 207 : 'HEXAFD', 00240 208 : 'QUADFD', 00241 209 : 'PENTAFD', 00242 210 : 'TETRAFD', 00243 211 : 'TRIAFD', 00244 212 : 'TRIAX3FD', 00245 213 : 'TRIAXFD', 00246 214 : 'QUADX4FD', 00247 215 : 'QUADXFD', 00248 216 : 'TETRA4FD', 00249 217 : 'TRIA3FD', 00250 218 : 'HEXAFD', 00251 219 : 'QUADFD', 00252 220 : 'PENTAFD', 00253 221 : 'TETRAFD', 00254 222 : 'TRIAX3FD', 00255 223 : 'QUADXFD', 00256 224 : 'ELAS1', 00257 225 : 'ELAS3', 00258 226 : 'BUSH', 00259 227 : 'RBAR', 00260 228 : 'RBE1', 00261 229 : 'RBE3', 00262 230 : 'RJOINT', 00263 231 : 'RROD', 00264 232 : 'QUADRLC', 00265 233 : 'TRIARLC', 00266 234 : '???', 00267 235 : 'CQUADR', # was blank in DMAP, found reference in OEF table 00268 236 : 'CTRIAR', # was blank in DMAP, found reference in OEF table 00269 } 00270 return elements[eCode] # +'_'+str(eCode) 00271 00272 def printTableCode(self,tableCode): 00273 tableCodeContent = tableCode%1000 00274 #dataFormat = tableCode/1000 00275 msg = '' 00276 #msg += 'tableCodeContent=%s dataFormat=%s\n' %(tableCodeContent,dataFormat) 00277 00278 tableContent = { 00279 0 : '', 00280 1 : 'OUG - Displacement vector', 00281 2 : 'OPG - Load vector', 00282 3 : 'OQG - SPC Force vector', 00283 4 : 'OEF - Element force/flux', 00284 5 : 'OES - Element stress/strain', 00285 6 : 'LAMA - Eigenvalue summary', 00286 7 : 'OUG - Eigenvector', 00287 8 : None, 00288 9 : 'OEIGS - Eigenvalue analysis summary', 00289 10 : 'OUG - Velocity vector', 00290 11 : 'OUG - Acceleration vector', 00291 12 : 'OPG - Nonlinear force vector', 00292 13 : 'OGPWG - Grid point weight generator', 00293 14 : 'OUG - Eigenvector (solution set)', 00294 15 : 'OUG - Displacement vector (solution set)', 00295 16 : 'OUG - Velocity vector (solution set)', 00296 17 : 'OUG - Acceleration vector (solutin set)', 00297 18 : 'OEE - Element strain energy', 00298 19 : 'OGF - Grid point force balance', 00299 20 : 'OES - Stresses at grid points', 00300 21 : 'OES - Strain/curvature at grid points', 00301 22 : 'OELOF1 - Element internal forces/moments', 00302 23 : 'OELOP1 - Summation of element oriented forces on adjacent elements', 00303 24 : 'OEP - Element pressures', 00304 25 : 'OEF - Composite failure indices', 00305 26 : 'OGS - Grid point stresses (surface)', 00306 27 : 'OGS - Grid point stresses (volume - direct)', 00307 28 : 'OGS - Grid point stresses (volume - princial)', 00308 29 : 'OGS - Element stress discontinuities (surface)', 00309 30 : 'OGS - Element stress discontinuities (volume - direct)', 00310 31 : 'OGS - Element stress discontinuities (volume - princial)', 00311 32 : 'OGS - Grid point stress discontinuities (surface)', 00312 33 : 'OGS - Grid point stress discontinuities (volume - direct)', 00313 34 : 'OGS - Grid point stress discontinuities (volume - princial)', 00314 35 : 'OGS - Grid point stresses (plane stress)', 00315 36 : 'OEE - Element kinetic energy', 00316 37 : 'OEE - Element energy loss', 00317 38 : 'OMM - MaxMin summary', 00318 39 : 'OQG - MPC forces', 00319 40 : 'OGPKE - Grip point kinetic energy', 00320 51 : 'OFMPF2M - ???', 00321 52 : 'OSMPF2M - ???', 00322 53 : 'OPMPF2M - ???', 00323 54 : 'OLMPF2M - ???', 00324 55 : 'OGMPF2M - ???', 00325 } 00326 msg += 'n=%s table=%s-%s' %(self.n,self.tableName, 00327 tableContent[tableCodeContent]) 00328 return msg 00329 00330 def codeInformation(self): 00331 """ 00332 prints the general table information 00333 DMAP - page 60-63 00334 """ 00335 deviceCode = self.deviceCode 00336 #analysisCode = self.analysisCode 00337 #tableCode = self.tableCode 00338 sortCode = self.sortCode 00339 00340 formatCode = None 00341 if hasattr(self, 'formatCode'): 00342 formatCode = self.formatCode 00343 00344 sCode = None 00345 if hasattr(self, 'sCode'): 00346 sCode = self.sCode 00347 00348 thermal = None 00349 if hasattr(self, 'thermal'): 00350 thermal = self.thermal 00351 00352 stressWord = '' 00353 if hasattr(self, 'stressBits'): 00354 if self.isStress():# 00355 stressWord = 'Stress' 00356 else: 00357 stressWord = 'Strain' 00358 ### 00359 ### 00360 00361 elementType = None 00362 if hasattr(self, 'elementType'): 00363 elementType = self.elementType 00364 00365 sWord = '' 00366 if( sCode==0): sWord += 'Coordinate Element - Stress Max Shear (Octahedral)' 00367 elif(sCode==14): sWord += 'Coordinate Element - Strain Fiber Max Shear (Octahedral)' 00368 00369 elif(sCode==1): sWord += 'Coordinate Element - Stress von Mises' 00370 elif(sCode==10): sWord += 'Coordinate Element - Strain Curvature Max Shear (Octahedral)' 00371 00372 elif(sCode==11): sWord += 'Coordinate Element - Strain Curvature von Mises' 00373 elif(sCode==15): sWord += 'Coordinate Element - Strain Fiber von Mises' 00374 00375 elif(sCode==16): sWord += 'Coordinate Material - Stress Max Shear (Octahedral)' 00376 elif(sCode==17): sWord += 'Coordinate Material - Stress von Mises' 00377 00378 elif(sCode==26): sWord += 'Coordinate Material - Strain Curvature Max Shear' 00379 elif(sCode==30): sWord += 'Coordinate Material - Strain Fiber Max Shear (Octahedral)' 00380 00381 elif(sCode==27): sWord += 'Coordinate Material - Strain Curvature von Mises' 00382 elif(sCode==31): sWord += 'Coordinate Material - Strain Fiber von Mises' 00383 else: 00384 #sWord = 'Stress or Strain - UNDEFINED' 00385 sWord = '' 00386 00387 formatWord = '???' 00388 if( formatCode==1): formatWord = "Real" 00389 elif(formatCode==2): formatWord = "Real/Imaginary" 00390 elif(formatCode==3): formatWord = "Magnitude/Phase" 00391 else: 00392 formatWord = '???' 00393 #msg = 'unsupported formatCode: formatCode=%s\n' %(formatCode) 00394 #raise InvalidFormatCodeError(msg) 00395 00396 if self.sortBits[0]==0: sortWord1 = 'Sort1' 00397 else: sortWord1 = 'Sort2' 00398 if self.sortBits[1]==0: sortWord2 = 'Real' 00399 else: sortWord2 = 'Real/Imaginary' 00400 if self.sortBits[2]==0: sortWord3 = 'Sorted Responses' 00401 else: sortWord3 = 'Random Responses' 00402 00403 #if( self.sortCode==0): sortWord = 'Real' 00404 #elif(self.sortCode==1): sortWord = 'Real/Imaginary' 00405 #elif(self.sortCode==2): sortWord = 'Random Responses' 00406 #else: 00407 #sortWord = '???' 00408 #msg = 'unsupported sortCode: sortCode=%s\n' %(sortCode) 00409 #print msg 00410 #raise RuntimeError(msg) 00411 00412 if( thermal==0): thermalWord = 'isHeatTransfer = False' 00413 elif(thermal==1): thermalWord = 'isHeatTransfer = True' 00414 elif(thermal==2): thermalWord = 'Scaled response spectra ABS' 00415 elif(thermal==3): thermalWord = 'Scaled response spectra SRSS' 00416 elif(thermal==4): thermalWord = 'Scaled response spectra NRL' 00417 elif(thermal==5): thermalWord = 'Scaled response spectra NRLO' 00418 else: 00419 thermalWord = '???' 00420 #msg = 'unsupported thermal: thermal=%s\n' %(thermal) 00421 #raise ValueError(msg) 00422 00423 analysis='???' 00424 if( self.analysisCode== 1): analysis = "Statics" 00425 elif(self.analysisCode== 2): analysis = "Normal modes or buckling (real eigenvalues)" 00426 elif(self.analysisCode== 3): analysis = "Differential Stiffness 0 - obsolete" 00427 elif(self.analysisCode== 4): analysis = "Differential Stiffness 1 - obsolete" 00428 elif(self.analysisCode== 5): analysis = "Frequency" 00429 elif(self.analysisCode== 6): analysis = "Transient" 00430 elif(self.analysisCode== 7): analysis = "Pre-buckling" 00431 elif(self.analysisCode== 8): analysis = "Post-buckling" 00432 elif(self.analysisCode== 9): analysis = "Complex eigenvalues" 00433 elif(self.analysisCode==10): analysis = "Nonlinear statics" 00434 elif(self.analysisCode==11): analysis = "Geometric nonlinear statics" 00435 00436 device='???' 00437 if( self.deviceCode==1): device = "Print" 00438 elif(self.deviceCode==2): device = "Plot" 00439 elif(self.deviceCode==3): device = "Print and Plot" 00440 elif(self.deviceCode==4): device = "Punch" 00441 elif(self.deviceCode==5): device = "Print and Punch" 00442 elif(self.deviceCode==6): device = "Plot and Punch" 00443 elif(self.deviceCode==7): device = "Print, Plot, and Punch" 00444 00445 if thermal == 0: ForceFlux = 'Force' 00446 elif thermal==1: ForceFlux = 'Flux' 00447 else: ForceFlux = 'Force (or Flux)' 00448 00449 if thermal == 0: DispTemp = 'Displacement' 00450 elif thermal==1: DispTemp = 'Temperature' 00451 else: DispTemp = 'Displacement/Temperature' 00452 00453 table = '???' 00454 if( self.tableCode== 1): table = "OUG - %s vector/scalar" %(DispTemp) 00455 elif(self.tableCode== 2): table = "OPG - Load vector" 00456 elif(self.tableCode== 3): table = "OQG - SPC Force vector" 00457 elif(self.tableCode== 4): table = "OEF - Element %s" %(ForceFlux) 00458 elif(self.tableCode== 5): table = "OES - Element %s" %(stressWord) 00459 elif(self.tableCode== 6): table = "LAMA - Eigenvalue summary" 00460 elif(self.tableCode== 7): table = "OUG - Eigenvector" 00461 elif(self.tableCode== 8): table = "none - Grid point singularity table (obsolete)" 00462 elif(self.tableCode== 9): table = "OEIGS - Eigenvalue analysis summary" 00463 elif(self.tableCode==10): table = "OUG - Velocity vector" 00464 elif(self.tableCode==11): table = "OUG - Acceleration vector" 00465 elif(self.tableCode==12): table = "OPG - Nonlinear force vector" 00466 elif(self.tableCode==13): table = "OGPWG - Grid point weight generator" 00467 elif(self.tableCode==14): table = "OUG - Eigenvector (solution set)" 00468 elif(self.tableCode==15): table = "OUG - Displacement vector (solution set)" 00469 elif(self.tableCode==16): table = "OUG - Velocity vector (solution set)" 00470 elif(self.tableCode==17): table = "OUG - Acceleration vector (solution set)" 00471 elif(self.tableCode==18): table = "OEE - Element strain energy" 00472 elif(self.tableCode==19): table = "OGF - Grid point force balance" 00473 elif(self.tableCode==20): table = "OES - Stresses at grid points (from the CURV module)" 00474 elif(self.tableCode==21): table = "OES - Strain/curvature at grid points" 00475 elif(self.tableCode==22): table = "OELOF1 - Element internal forces and moments" 00476 elif(self.tableCode==23): table = "OELOP1 - Summation of element oriented forces on adjacent elements" 00477 elif(self.tableCode==24): table = "OEP - Element pressures" 00478 elif(self.tableCode==25): table = "OEF - Composite failure indicies" 00479 elif(self.tableCode==26): table = "OGS - Grid point stresses (surface)" 00480 elif(self.tableCode==27): table = "OGS - Grid point stresses (volume -- direct)" 00481 elif(self.tableCode==28): table = "OGS - Grid point stresses (volume -- principal)" 00482 elif(self.tableCode==29): table = "OGS - Element stress discontinuities (surface)" 00483 elif(self.tableCode==30): table = "OGS - Element stress discontinuities (volume -- direct)" 00484 elif(self.tableCode==31): table = "OGS - Element stress discontinuities (volume -- principal)" 00485 elif(self.tableCode==32): table = "OGS - Grid point stress discontinuities (surface)" 00486 elif(self.tableCode==33): table = "OGS - Grid point stress discontinuities (volume -- direct)" 00487 elif(self.tableCode==34): table = "OGS - Grid point stress discontinuities (volume -- principal)" 00488 elif(self.tableCode==35): table = "OGS - Grid point stress discontinuities (plane strain)" 00489 elif(self.tableCode==36): table = "OEE - Element kinetic energy" 00490 elif(self.tableCode==37): table = "OEE - Element energy loss" 00491 elif(self.tableCode==38): table = "OMM - Max/Min summary" 00492 elif(self.tableCode==39): table = "OQG - MPC Forces" 00493 elif(self.tableCode==40): table = "OGPKE - Grip point kinetic energy" 00494 00495 msg = '--Table3Data--\n\n' 00496 msg += " deviceCode = %-3s %s\n" %(self.deviceCode,device) 00497 msg += " analysisCode = %-3s %s\n" %(self.analysisCode,analysis) 00498 msg += " tableCode = %-3s %s-%s\n" %(self.tableCode,self.tableName,table) 00499 msg += " formatCode = %-3s %s\n" %(formatCode,formatWord) 00500 00501 msg += " sortType = %-3s %s\n" %(self.sortBits[0],sortWord1) 00502 msg += " dataFormat = %-3s %s\n" %(self.sortBits[1],sortWord2) 00503 msg += " isRandom = %-3s %s\n" %(self.sortBits[2],sortWord3) 00504 00505 if elementType is not None: 00506 msg += " elementType = %-3s %s\n" %(elementType,self.ElementType(elementType)) 00507 if sWord: # stress code 00508 msg += " sCode = %-3s %s\n" %(sCode,sWord) 00509 if thermal is not None: 00510 msg += " thermal = %-3s %s\n" %(thermal,thermalWord) 00511 msg += " numWide = %-3s\n" %(self.numWide) 00512 msg += " iSubcase = %-3s\n" %(self.iSubcase) 00513 #print msg 00514 return msg 00515 00516 #---- 00517 def isThermal(self): 00518 if self.thermal==0: 00519 return False 00520 elif self.thermal==1: 00521 return True 00522 return '???' 00523 00524 #---- 00525 # formatCode 3 00526 def isMagnitudePhase(self): 00527 if self.formatCode==3: 00528 return True 00529 return False 00530 00531 #---- 00532 # sortCode 0 00533 def isSort1(self): 00534 if self.sortBits[0]==0: 00535 return True 00536 return False 00537 00538 def isSort2(self): 00539 return not(self.isSort1()) 00540 00541 #---- 00542 # sortCode 1 00543 def isReal(self): # formatCode=1, this one is tricky b/c you can overwrite the Real code 00544 #if self.formatCode==1: 00545 # return True 00546 if self.sortBits[1]==0: 00547 return True 00548 return False 00549 00550 def isRealImaginary(self): # formatCode=2...does that dominate? 00551 return not(self.isReal()) 00552 00553 #---- 00554 # sortCode 2 00555 def isSortedResponse(self): 00556 if self.sortBits[2]==0: 00557 return True 00558 return False 00559 00560 def isRandomResponse(self): 00561 return not(self.isSortedResponse()) 00562 00563 #---- 00564 # combos 00565 def isRealOrRandom(self): 00566 return self.isReal() or self.isRandom() 00567 00568 def isRealImaginaryOrMagnitudePhase(self): 00569 return self.isRealImaginary or self.MagnitudePhase() 00570 00571 #---- 00572 def isStress(self): 00573 if self.stressBits[1]==0: 00574 return True 00575 return False 00576