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 # http://www.cadfamily.com/online-help/I-DEAS/SDRCHelp/LANG/English/slv_ug/NAS_results_imported.htm 00026 #import sys 00027 from struct import unpack 00028 00029 from pyNastran.op2.tables.oug.oug_displacements import ( 00030 DisplacementObject, # tableCode=1 formatCode=1 sortCode=0 00031 ComplexDisplacementObject) # analysisCode=5 formatCode=3 sortCode=1 00032 00033 # tableCode=10 formatCode=1 sortCode=0 00034 from pyNastran.op2.tables.oug.oug_velocities import ( 00035 VelocityObject, ComplexVelocityObject) 00036 00037 # tableCode=11 formatCode=1 sortCode=0 00038 from pyNastran.op2.tables.oug.oug_accelerations import ( 00039 AccelerationObject, ComplexAccelerationObject) 00040 00041 # tableCode=1 formatCode=1 sortCode=0 00042 from pyNastran.op2.tables.oug.oug_temperatures import ( 00043 TemperatureObject) 00044 00045 from pyNastran.op2.tables.oug.oug_eigenvectors import ( 00046 EigenVectorObject, # analysisCode=2, sortCode=0 formatCode tableCode=7 00047 ComplexEigenVectorObject, # analysisCode=5, sortCode=1 formatCode=1 tableCode=7 00048 #RealEigenVectorObject, # analysisCode=9, sortCode=1 formatCode=1 tableCode=7 00049 ) 00050 from pyNastran.op2.tables.opg_appliedLoads.opg_loadVector import ThermalVelocityVectorObject 00051 from pyNastran.op2.op2_helper import polarToRealImag 00052 00053 class OUG(object): 00054 """Table of displacements/velocities/acceleration/heat flux/temperature""" 00055 00056 def readTable_OUG(self): 00057 #self.tableName = 'OUG' 00058 table3 = self.readTable_OUG_3 00059 table4Data = self.readOUG_Data 00060 self.readResultsTable(table3, table4Data) 00061 self.deleteAttributes_OUG() 00062 00063 def deleteAttributes_OUG(self): 00064 params = ['lsdvm', 'mode', 'eigr', 'modeCycle', 'freq', 'dt', 'lftsfq', 00065 'thermal', 'randomCode', 'fCode', 'numWide', 'acousticFlag'] 00066 self.deleteAttributes(params) 00067 00068 def readTable_OUG_3(self, iTable): # iTable=-3 00069 bufferWords = self.getMarker() 00070 if self.makeOp2Debug: 00071 self.op2Debug.write('bufferWords=%s\n' %(str(bufferWords))) 00072 #print "2-bufferWords = ",bufferWords,bufferWords*4,'\n' 00073 00074 data = self.getData(4) 00075 bufferSize, = unpack('i', data) 00076 data = self.getData(4*50) 00077 #print self.printBlock(data) 00078 00079 (three) = self.parseApproachCode(data) 00080 00081 ## random code 00082 self.addDataParameter(data, 'randomCode', 'i', 8, False) 00083 ## format code 00084 self.addDataParameter(data, 'formatCode', 'i', 9, False) 00085 ## number of words per entry in record; @note is this needed for this table ??? 00086 self.addDataParameter(data, 'numWide', 'i', 10, False) 00087 ## acoustic pressure flag 00088 self.addDataParameter(data, 'acousticFlag', 'f', 13, False) 00089 ## thermal flag; 1 for heat transfer, 0 otherwise 00090 self.addDataParameter(data, 'thermal', 'i', 23, False) 00091 self.isFlipped = False 00092 if self.isSort1(): 00093 ## assuming tCode=1 00094 if self.analysisCode == 1: # statics / displacement / heat flux 00095 self.addDataParameter(data,'lsdvmn', 'i',5,False) ## load set number 00096 self.applyDataCodeValue('dataNames',['lsdvmn']) 00097 self.setNullNonlinearFactor() 00098 elif self.analysisCode == 2: # real eigenvalues 00099 self.addDataParameter(data,'mode', 'i',5) ## mode number 00100 self.addDataParameter(data,'eigr', 'f',6,False) ## real eigenvalue 00101 self.addDataParameter(data,'modeCycle','i',7,False) ## mode or cycle @todo confused on the type - F1??? 00102 self.applyDataCodeValue('dataNames',['mode','eigr','modeCycle']) 00103 #elif self.analysisCode==3: # differential stiffness 00104 #self.lsdvmn = self.getValues(data,'i',5) ## load set number 00105 #self.dataCode['lsdvmn'] = self.lsdvmn 00106 #elif self.analysisCode==4: # differential stiffness 00107 #self.lsdvmn = self.getValues(data,'i',5) ## load set number 00108 elif self.analysisCode == 5: # frequency 00109 self.addDataParameter(data,'freq','f',5) ## frequency 00110 self.applyDataCodeValue('dataNames',['freq']) 00111 elif self.analysisCode == 6: # transient 00112 self.addDataParameter(data,'dt','f',5) ## time step 00113 self.applyDataCodeValue('dataNames',['dt']) 00114 elif self.analysisCode == 7: # pre-buckling 00115 self.addDataParameter(data,'lsdvmn', 'i',5) ## load set number 00116 self.applyDataCodeValue('dataNames',['lsdvmn']) 00117 elif self.analysisCode == 8: # post-buckling 00118 self.addDataParameter(data,'lsdvmn', 'i',5) ## load set number 00119 self.addDataParameter(data,'eigr', 'f',6,False) ## real eigenvalue 00120 self.applyDataCodeValue('dataNames',['lsdvmn','eigr']) 00121 elif self.analysisCode == 9: # complex eigenvalues 00122 self.addDataParameter(data,'mode','i',5) ## mode number 00123 self.addDataParameter(data,'eigr','f',6,False) ## real eigenvalue 00124 self.addDataParameter(data,'eigi','f',7,False) ## imaginary eigenvalue 00125 self.applyDataCodeValue('dataNames',['mode','eigr','eigi']) 00126 elif self.analysisCode == 10: # nonlinear statics 00127 self.addDataParameter(data,'lftsfq','f',5) ## load step 00128 self.applyDataCodeValue('dataNames',['lftsfq']) 00129 elif self.analysisCode == 11: # old geometric nonlinear statics 00130 self.addDataParameter(data,'lsdvmn', 'i',5) ## load set number 00131 self.applyDataCodeValue('dataNames',['lsdvmn']) 00132 elif self.analysisCode == 12: # contran ? (may appear as aCode=6) --> straight from DMAP...grrr... 00133 self.addDataParameter(data,'lsdvmn', 'i',5) ## load set number 00134 self.applyDataCodeValue('dataNames',['lsdvmn']) 00135 else: 00136 raise RuntimeError('invalid analysisCode...analysisCode=%s' %(self.analysisCode)) 00137 else: # sort2 00138 00139 eidDevice = self.getValues(data,'i',5) 00140 floatVal = self.getValues(data,'f',5) 00141 #eid = (eidDevice-self.deviceCode)//10 00142 #print("EID = %s" %(eidDevice)) 00143 #print("floatVal = %s" %(floatVal)) 00144 00145 if self.tableName=='OUGRMS2' and self.analysisCode==1: 00146 self.addDataParameter(data,'nodeID','i',5,fixDeviceCode=True) ## frequency 00147 self.applyDataCodeValue('dataNames',['nodeID']) 00148 00149 #self.isRegular = False 00150 elif self.analysisCode in [1,5]: # 5 # freq 00151 self.addDataParameter(data,'nodeID','i',5,fixDeviceCode=True) ## frequency 00152 self.applyDataCodeValue('dataNames',['nodeID']) 00153 #print("nodeID = %s" %(self.nodeID)) 00154 #sys.exit(self.nodeID) 00155 elif self.analysisCode==6: # transient dt 00156 self.addDataParameter(data,'nodeID','i',5,fixDeviceCode=True) ## time step 00157 self.applyDataCodeValue('dataNames',['nodeID']) 00158 elif self.analysisCode==10: # freq/time step fqts 00159 self.addDataParameter(data,'nodeID','i',5,fixDeviceCode=True) ## frequency / time step 00160 self.applyDataCodeValue('dataNames',['nodeID']) 00161 else: 00162 self.isRegular = True 00163 self.addDataParameter(data,'nodeID','i',5,fixDeviceCode=True) ## node ID 00164 self.applyDataCodeValue('dataNames',['nodeID']) 00165 # tCode=2 00166 #if self.analysisCode==2: # sort2 00167 # self.lsdvmn = self.getValues(data,'i',5) 00168 00169 #print "*iSubcase=%s"%(self.iSubcase) 00170 #print "analysisCode=%s tableCode=%s thermal=%s" %(self.analysisCode,self.tableCode,self.thermal) 00171 #print self.codeInformation() 00172 00173 if not self.isSort1(): 00174 raise NotImplementedError('sort2...') 00175 00176 #self.printBlock(data) 00177 self.readTitle() 00178 00179 def getOUG_FormatStart(self): 00180 """ 00181 Returns an i or an f depending on if it's SORT2 or not. 00182 Also returns an extraction function that is called on the first argument 00183 """ 00184 isSort1 = self.isSort1() 00185 if self.tableName == 'OUGRMS2' and self.analysisCode == 1: 00186 format1 = 'i' # SORT2 00187 extract = self.extractSort2 00188 00189 elif isSort1: 00190 #print "SORT1 - %s" %(self.ElementType(self.elementType)) 00191 #print "SORT1" 00192 format1 = 'i' # SORT1 00193 extract = self.extractSort1 00194 #if self.analysisCode in [5]: 00195 #extract==self.extractSort2 00196 else: # values from IDENT #@todo test this... 00197 #print "SORT2" 00198 #print "SORT2 - %s" %(self.ElementType(self.elementType)) 00199 if self.analysisCode in [2,3,4,6,7,8,11]: 00200 format1 = 'f' # SORT2 00201 extract = self.extractSort2 00202 elif self.analysisCode in [5]: 00203 format1 = 'f' 00204 extract = self.extractSort2 00205 elif self.analysisCode in [1,9,10,12]: 00206 format1 = 'f' # SORT1 00207 extract = self.extractSort2 00208 else: 00209 raise KeyError('invalid analysisCode...analysisCode=%s' %(self.analysisCode)) 00210 ### 00211 #eid = self.nonlinearFactor 00212 return (format1,extract) 00213 00214 def readOUG_Data(self): 00215 #print "self.analysisCode=%s tableCode(1)=%s thermal(23)=%g" %(self.analysisCode,self.tableCode,self.thermal) 00216 #tfsCode = [self.tableCode,self.formatCode,self.sortCode] 00217 00218 #print self.dataCode 00219 #print "tfsCode=%s" %(tfsCode) 00220 00221 if self.tableCode == 1 and self.tableName in ['OUGV1','OUPV1']: # displacement 00222 if self.tableName=='OUGV1': 00223 assert self.tableName in ['OUGV1'],'tableName=%s tableCode=%s\n%s' %(self.tableName,self.tableCode,self.codeInformation()) 00224 self.readOUG_Data_table1() 00225 else: # 'OUPV1' 00226 self.NotImplementedOrSkip('bad approach/table/format/sortCode=%s on %s-OUG table' %(self.atfsCode,self.tableName)) 00227 elif self.tableCode == 1 and self.tableName in ['OUGATO2','OUGCRM2','OUGPSD2','OUGRMS2','OUGNO2',]: # displacement 00228 #assert self.tableName in ['OUGATO2','OUGCRM2','OUGPSD2','OUGRMS2','OUGNO2',],'tableName=%s tableCode=%s\n%s' %(self.tableName,self.tableCode,self.codeInformation()) 00229 self.readOUG_Data_table1() 00230 elif self.tableCode == 7: # modes 00231 if self.tableName=='OUGV1': 00232 assert self.tableName in ['OUGV1'],'tableName=%s tableCode=%s\n%s' %(self.tableName,self.tableCode,self.codeInformation()) 00233 self.readOUG_Data_table7() 00234 else: 00235 self.NotImplementedOrSkip('bad approach/table/format/sortCode=%s on %s-OUG table' %(self.atfsCode,self.tableName)) 00236 elif self.tableCode == 10: # velocity 00237 if self.tableName=='OUGV1': 00238 assert self.tableName in ['OUGV1'],'tableName=%s tableCode=%s\n%s' %(self.tableName,self.tableCode,self.codeInformation()) 00239 self.readOUG_Data_table10() 00240 else: 00241 self.NotImplementedOrSkip('bad approach/table/format/sortCode=%s on %s-OUG table' %(self.atfsCode,self.tableName)) 00242 elif self.tableCode == 11: # Acceleration vector 00243 if self.tableName=='OUGV1': 00244 assert self.tableName in ['OUGV1'],'tableName=%s tableCode=%s\n%s' %(self.tableName,self.tableCode,self.codeInformation()) 00245 self.readOUG_Data_table11() 00246 else: 00247 self.NotImplementedOrSkip('bad approach/table/format/sortCode=%s on %s-OUG table' %(self.atfsCode,self.tableName)) 00248 else: 00249 #self.log.debug('skipping approach/table/format/sortCode=%s on %s-OUG table' %(self.atfsCode,self.tableName)) 00250 self.NotImplementedOrSkip('bad approach/table/format/sortCode=%s on %s-OUG table' %(self.atfsCode,self.tableName)) 00251 ### 00252 #print self.obj 00253 00254 00255 def readThermal4(self): # used on self.thermal in [2,4,8]: 00256 #print self.codeInformation() 00257 #print self.printBlock(self.data) 00258 n = 0 00259 nEntries = len(self.data)//32 00260 for i in xrange(nEntries): 00261 eData = self.data[n:n+32] 00262 out = unpack('2i6f', eData) 00263 #nid = (out[0]-self.deviceCode)//10 ## @todo fix the deviceCode 00264 00265 #print out 00266 n+=32 00267 #print "nid = ",nid 00268 #sys.exit('thermal4...') 00269 00270 def readOUG_Data_table1(self): # displacement / temperature OUGV1, OUPV1 00271 """ 00272 OUGV1 - global coordinate system in sort 1 00273 OUPV1 - scaled response spectra in sort 1 00274 OUGPSD2 - PSD in sort 2 00275 OUGATO2 - auto-correlated in sort 2 00276 """ 00277 isSkip = False 00278 if self.numWide == 8: # real/random 00279 if self.thermal == 0: 00280 #print self.dataCode 00281 if self.tableName in ['OUGV1']: 00282 resultName = 'displacements' 00283 self.createTransientObject(self.displacements,DisplacementObject) # real 00284 elif self.tableName in ['OUGATO2']: 00285 resultName = 'displacementsATO' 00286 self.createTransientObject(self.displacementsATO,DisplacementObject) # random 00287 elif self.tableName in ['OUGCRM2']: 00288 resultName = 'displacementsCRM' 00289 self.createTransientObject(self.displacementsCRM,DisplacementObject) # random 00290 elif self.tableName in ['OUGPSD2']: 00291 resultName = 'displacementsPSD' 00292 self.createTransientObject(self.displacementsPSD,DisplacementObject) # random 00293 elif self.tableName in ['OUGRMS2']: 00294 resultName = 'displacementsRMS' 00295 self.createTransientObject(self.displacementsRMS,DisplacementObject) # random 00296 elif self.tableName in ['OUGNO2']: 00297 resultName = 'displacementsNO' 00298 self.createTransientObject(self.displacementsNO,DisplacementObject) # random 00299 else: 00300 isSkip = True 00301 self.NotImplementedOrSkip('***table=%s***\n%s' %(self.tableName,self.codeInformation())) 00302 if not isSkip: 00303 self.handleResultsBuffer3(self.OUG_RealTable,resultName) 00304 elif self.thermal == 1: 00305 resultName = 'temperatures' 00306 self.createTransientObject(self.temperatures,TemperatureObject) 00307 self.handleResultsBuffer3(self.OUG_RealTable,resultName) 00308 #elif self.thermal == 8: 00309 #resultName = 'scaledDisplacements' 00310 #self.createTransientObject(self.scaledDisplacements,displacementObject) 00311 #self.handleResultsBuffer3(self.OUG_RealTable,resultName) 00312 else: 00313 self.NotImplementedOrSkip('***thermal=%s***\n%s' %(self.thermal,self.codeInformation())) 00314 elif self.numWide == 14: # real/imaginary or mag/phase 00315 if self.thermal == 0: 00316 resultName = 'displacements' 00317 self.createTransientObject(self.displacements,ComplexDisplacementObject) # complex 00318 self.handleResultsBuffer3(self.OUG_ComplexTable,resultName) 00319 else: 00320 self.NotImplementedOrSkip() 00321 else: 00322 self.NotImplementedOrSkip('only numWide=8 or 14 is allowed numWide=%s' %(self.numWide)) 00323 ### 00324 00325 def readOUG_Data_table7(self): # eigenvector 00326 #isSort1 = self.isSort1() 00327 if self.numWide==8: # real/random 00328 if self.thermal == 0: 00329 resultName = 'eigenvectors' 00330 self.createTransientObject(self.eigenvectors,EigenVectorObject) # real 00331 self.handleResultsBuffer3(self.OUG_RealTable,resultName) 00332 else: 00333 self.NotImplementedOrSkip() 00334 elif self.numWide==14: # real/imaginary or mag/phase 00335 if self.thermal == 0: 00336 resultName = 'eigenvectors' 00337 self.createTransientObject(self.eigenvectors,ComplexEigenVectorObject) # complex 00338 self.handleResultsBuffer3(self.OUG_ComplexTable,resultName) 00339 else: 00340 self.NotImplementedOrSkip() 00341 else: 00342 self.NotImplementedOrSkip('only numWide=8 or 14 is allowed numWide=%s' %(self.numWide)) 00343 ### 00344 00345 def readOUG_Data_table10(self): # velocity 00346 if self.numWide == 8: # real/random 00347 if self.thermal == 0: 00348 resultName = 'velocities' 00349 self.createTransientObject(self.velocities,VelocityObject) # real 00350 self.handleResultsBuffer3(self.OUG_RealTable, resultName) 00351 elif self.thermal == 1: 00352 resultName = 'velocities' 00353 self.createTransientObject(self.velocities,ThermalVelocityVectorObject) # real 00354 self.handleResultsBuffer3(self.OUG_RealTable, resultName) 00355 else: 00356 self.NotImplementedOrSkip() 00357 elif self.numWide == 14: # real/imaginary or mag/phase 00358 if self.thermal == 0: 00359 resultName = 'velocities' 00360 self.createTransientObject(self.velocities, ComplexVelocityObject) # complex 00361 self.handleResultsBuffer3(self.OUG_ComplexTable,resultName) 00362 else: 00363 self.NotImplementedOrSkip() 00364 else: 00365 self.NotImplementedOrSkip('only numWide=8 or 14 is allowed numWide=%s' %(self.numWide)) 00366 00367 def readOUG_Data_table11(self): # acceleration 00368 if self.numWide == 8: # real/random 00369 if self.thermal == 0: 00370 resultName = 'accelerations' 00371 self.createTransientObject(self.accelerations,AccelerationObject) # real 00372 self.handleResultsBuffer3(self.OUG_RealTable,resultName) 00373 else: 00374 self.NotImplementedOrSkip() 00375 elif self.numWide == 14: # real/imaginary or mag/phase 00376 if self.thermal == 0: 00377 resultName = 'accelerations' 00378 self.createTransientObject(self.accelerations,ComplexAccelerationObject) # complex 00379 self.handleResultsBuffer3(self.OUG_ComplexTable,resultName) 00380 else: 00381 self.NotImplementedOrSkip() 00382 else: 00383 self.NotImplementedOrSkip('only numWide=8 or 14 is allowed numWide=%s' %(self.numWide)) 00384 00385 def OUG_RealTable(self): 00386 dt = self.nonlinearFactor 00387 (format1,extract) = self.getOUG_FormatStart() 00388 format1 += 'i6f' 00389 00390 #print "len(data) = ",len(self.data) 00391 while len(self.data) >= 32: # 8*4 00392 eData = self.data[0:32] 00393 self.data = self.data[32: ] 00394 #print "len(data) = ",len(eData) 00395 00396 out = unpack(format1, eData) 00397 (eid, gridType, tx, ty, tz, rx, ry, rz) = out 00398 eid2 = extract(eid,dt) 00399 #print "eType=%s" %(eType) 00400 00401 dataIn = [eid2, gridType, tx, ty, tz, rx, ry, rz] 00402 #print "%s" %(self.ElementType(self.elementType)),dataIn 00403 #print "%s" %(self.tableName),dataIn 00404 #eid = self.obj.addNewEid(out) 00405 self.obj.add(dt,dataIn) 00406 #print "len(data) = ",len(self.data) 00407 ### 00408 00409 def OUG_ComplexTable(self): 00410 dt = self.nonlinearFactor 00411 00412 (format1,extract) = self.getOUG_FormatStart() 00413 format1 += 'i12f' 00414 #print "format1 = ",format1 00415 isMagnitudePhase = self.isMagnitudePhase() 00416 00417 while len(self.data) >= 56: # 14*4 00418 eData = self.data[0:56] 00419 self.data = self.data[56: ] 00420 #print "len(data) = ",len(eData) 00421 00422 out = unpack(format1, eData) 00423 (eid, gridType, txr, tyr, tzr, rxr, ryr, rzr, 00424 txi, tyi, tzi, rxi, ryi, rzi) = out 00425 00426 if isMagnitudePhase: 00427 tx = polarToRealImag(txr, txi); rx = polarToRealImag(rxr, rxi) 00428 ty = polarToRealImag(tyr, tyi); ry = polarToRealImag(ryr, ryi) 00429 tz = polarToRealImag(tzr, tzi); rz = polarToRealImag(rzr, rzi) 00430 else: 00431 tx = complex(txr, txi); rx = complex(rxr, rxi) 00432 ty = complex(tyr, tyi); ry = complex(ryr, ryi) 00433 tz = complex(tzr, tzi); rz = complex(rzr, rzi) 00434 00435 eid2 = extract(eid, dt) 00436 #print "eType=%s" %(eType) 00437 00438 dataIn = [eid2, gridType, tx, ty, tz, rx, ry, rz] 00439 #print "%s" %(self.ElementType(self.elementType)),dataIn 00440 #eid = self.obj.addNewEid(out) 00441 self.obj.add(dt, dataIn) 00442 #print "len(data) = ",len(self.data) 00443 ###