pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
oug.py
Go to the documentation of this file.
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         ###
 All Classes Namespaces Files Functions Variables