pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
opg.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 
00026 from __future__ import division, print_function
00027 #import sys
00028 from struct import unpack
00029 
00030 from .opg_Objects      import AppliedLoadsObject #ComplexAppliedLoadsObject
00031 from .opg_loadVector   import LoadVectorObject, ComplexLoadVectorObject, ThermalLoadVectorObject
00032 from .opnl_forceVector import ForceVectorObject, ComplexForceVectorObject
00033 
00034 # OGS table ## @todo move this...
00035 from ..ogf_gridPointForces.ogs_surfaceStresses import GridPointStressesObject,GridPointStressesVolumeObject
00036 
00037 class OPG(object):
00038     """Table of element forces"""
00039     def readTable_OPG(self):
00040         table3     = self.readTable_OPG_3
00041         table4Data = self.readOPG_Data
00042         self.readResultsTable(table3,table4Data)
00043         self.deleteAttributes_OPG()
00044 
00045     def deleteAttributes_OPG(self):
00046         params = ['lsdvm', 'mode', 'eigr', 'eign', 'eigi', 'modeCycle', 'freq',
00047                   'time', 'lftsfq', 'dLoadID', 'formatCode', 'numWide','oCode']
00048         self.deleteAttributes(params)
00049 
00050     def readTable_OPG_3(self, iTable): # iTable=-3
00051         bufferWords = self.getMarker()
00052         #print "2-bufferWords = ",bufferWords,bufferWords*4,'\n'
00053 
00054         data = self.getData(4)
00055         bufferSize, = unpack(b'i',data)
00056         data = self.getData(4*50)
00057         
00058         #self.printBlock(data)
00059         
00060         
00061         aCode = self.getBlockIntEntry(data,1)
00062         #print "aCode = ",aCode
00063         self.parseApproachCode(data)
00064         #iSubcase = self.getValues(data,'i',4)
00065 
00066         self.addDataParameter(data,'dLoadID',    'i', 8, False)   ## dynamic load set ID/random code
00067         self.addDataParameter(data,'formatCode', 'i', 9, False)   ## format code
00068         self.addDataParameter(data,'numWide',    'i', 10, False)  ## number of words per entry in record; @note is this needed for this table ???
00069         self.addDataParameter(data,'oCode',      'i', 11, False)   ## undefined in DMAP...
00070         self.addDataParameter(data,'thermal',    'i', 23, False)  ## thermal flag; 1 for heat ransfer, 0 otherwise
00071 
00072         #print "dLoadID(8)=%s formatCode(9)=%s numWide(10)=%s oCode(11)=%s thermal(23)=%s" %(self.dLoadID,self.formatCode,self.numWide,self.oCode,self.thermal)
00073         if not self.isSort1():
00074             raise NotImplementedError('sort2...')
00075         #assert self.isThermal()==False,self.thermal
00076         
00077         ## assuming tCode=1
00078         if self.analysisCode == 1:   # statics
00079             self.addDataParameter(data, 'lsdvmn', 'i', 5, False)   ## load set number
00080             self.applyDataCodeValue('dataNames', ['lsdvmn'])
00081             self.setNullNonlinearFactor()
00082         elif self.analysisCode == 2: # normal modes/buckling (real eigenvalues)
00083             self.addDataParameter(data,'mode',      'i', 5)   ## mode number
00084             self.addDataParameter(data, 'eign',      'f', 6, False)   ## real eigenvalue
00085             self.addDataParameter(data, 'modeCycle', 'f', 7, False)   ## mode or cycle @todo confused on the type - F1???
00086             self.applyDataCodeValue('dataNames', ['mode', 'eign', 'modeCycle'])
00087         #elif self.analysisCode == 3: # differential stiffness
00088         #    self.lsdvmn = self.getValues(data,'i',5) ## load set number
00089         #elif self.analysisCode == 4: # differential stiffness
00090         #    self.lsdvmn = self.getValues(data,'i',5) ## load set number
00091         elif self.analysisCode == 5:   # frequency
00092             self.addDataParameter(data,'freq', 'f', 5)   ## frequency
00093             self.applyDataCodeValue('dataNames', ['freq'])
00094         elif self.analysisCode == 6: # transient
00095             self.addDataParameter(data,'time', 'f', 5)   ## time step
00096             self.applyDataCodeValue('dataNames', ['time'])
00097         elif self.analysisCode == 7: # pre-buckling
00098             self.addDataParameter(data,'lsdvmn', 'i', 5)   ## load set number
00099             self.applyDataCodeValue('dataNames', ['lsdvmn'])
00100         elif self.analysisCode == 8: # post-buckling
00101             self.addDataParameter(data,'lsdvmn',  'i', 5)   ## load set number
00102             self.addDataParameter(data,'eigr',    'f', 6, False)   ## real eigenvalue
00103             self.applyDataCodeValue('dataNames', ['lsdvmn', 'eigr'])
00104         elif self.analysisCode == 9: # complex eigenvalues
00105             self.addDataParameter(data, 'mode', 'i', 5)   ## mode number
00106             self.addDataParameter(data, 'eigr', 'f', 6, False)   ## real eigenvalue
00107             self.addDataParameter(data, 'eigi', 'f', 7, False)   ## imaginary eigenvalue
00108             self.applyDataCodeValue('dataNames',['mode','eigr','eigi'])
00109         elif self.analysisCode == 10: # nonlinear statics
00110             self.addDataParameter(data,'lftsfq','f',5)   ## load step
00111             self.applyDataCodeValue('dataNames',['lftsfq'])
00112         elif self.analysisCode == 11: # old geometric nonlinear statics
00113             self.addDataParameter(data, 'lsdvmn', 'i', 5)   ## load set number
00114             self.applyDataCodeValue('dataNames', ['lsdvmn'])
00115         elif self.analysisCode == 12: # contran ? (may appear as aCode=6)  --> straight from DMAP...grrr...
00116             self.addDataParameter(data,'lsdvmn', 'i', 5)   ## load set number
00117             self.applyDataCodeValue('dataNames', ['lsdvmn'])
00118         else:
00119             raise RuntimeError('invalid analysisCode...analysisCode=%s' %(self.analysisCode))
00120         ###
00121         # tCode=2
00122         #if self.analysisCode==2: # sort2
00123         #    self.lsdvmn = self.getValues(data,'i',5) ## load set, Mode number
00124         
00125         #print "*iSubcase=%s"%(self.iSubcase)
00126         #print "analysisCode=%s tableCode=%s thermal=%s" %(self.analysisCode,self.tableCode,self.thermal)
00127         #print self.codeInformation()
00128 
00129         if not self.isSort1():
00130             raise NotImplementedError('sort2...')
00131 
00132         #self.printBlock(data)
00133         self.readTitle()
00134 
00135     def readOPG_Data(self):
00136         #print "self.analysisCode=%s tableCode(1)=%s thermal(23)=%g" %(self.analysisCode,self.tableCode,self.thermal)
00137         #tfsCode = [self.tableCode,self.formatCode,self.sortCode]
00138         self.atfsCode = [self.analysisCode,self.tableCode,self.formatCode,self.sortCode]
00139 
00140         
00141         if self.tableCode == 19:
00142             assert self.tableName in [None],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode)
00143             self.readOPG_Data_table19() # grid point force balance
00144         elif self.tableCode == 2:  # load vector
00145             assert self.tableName in ['OPG1','OPGV1'],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode)
00146             self.readOPG_Data_table2()
00147         elif self.tableCode == 12:  # nonlinear force vector
00148             assert self.tableName in ['OPNL1'],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode)
00149             self.readOPG_Data_table12()
00150         elif self.tableCode == 26:  # OGS1 - grid point stresses - surface
00151             assert self.tableName in ['OGS1'],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode)
00152             self.readOGS1_Data_table26()
00153         elif self.tableCode == 27:  # OGS1 - grid point stresses - volume direct
00154             assert self.tableName in ['OGS1'],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode)
00155             self.readOGS1_Data_table27()
00156 
00157         #elif self.tableCode == 28:  # OGS1- grid point stresses - principal
00158             #assert self.tableName in ['OGS1'],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode)
00159             #self.readOGS1_Data_table28()
00160             #self.NotImplementedOrSkip()
00161 
00162         #elif self.tableCode == 35:  # OGS - Grid point stress discontinuities (plane strain)
00163             #self.NotImplementedOrSkip()
00164         
00165         # OFMPF2M - does this belong here?
00166         #elif tfsCode==[51,3,3]:
00167         #    self.readOPG_Data_format3_sort3()
00168         
00169         # OSMPF2M - does this belong here?
00170         #elif tfsCode==[52,3,3]:
00171         #    self.readOPG_Data_format3_sort3()
00172         
00173         # OPMPF2M - does this belong here?
00174         #elif tfsCode==[53,3,3]:
00175         #    self.readOPG_Data_format3_sort3()
00176         
00177         # OLMPF2M - does this belong here?
00178         #elif tfsCode==[54,3,3]:
00179         #    self.readOPG_Data_format3_sort3()
00180 
00181         # OGMPF2M - does this belong here?
00182         #elif tfsCode==[55,3,3]:
00183         #    self.readOPG_Data_format3_sort3()
00184         else:
00185             self.NotImplementedOrSkip('bad tableCode/formatCode/sortCode=%s on %s-OPG table' %(self.atfsCode,self.tableName))
00186         ###
00187         #print self.obj
00188 
00189     def readOPG_Data_table2(self): # Load Vector
00190         #isSort1 = self.isSort1()
00191         #print "********\n",self.codeInformation()
00192         if self.numWide==8:  # real/random
00193             if self.thermal==0:
00194                 resultName = 'loadVectors'
00195                 self.createTransientObject(self.loadVectors,LoadVectorObject) # real
00196                 self.handleResultsBuffer3(self.OUG_RealTable,resultName)
00197             elif self.thermal==1:
00198                 resultName = 'thermalLoadVectors'
00199                 self.createTransientObject(self.thermalLoadVectors,ThermalLoadVectorObject) # real
00200                 self.handleResultsBuffer3(self.OUG_RealTable,resultName)
00201             else:
00202                 self.NotImplementedOrSkip()
00203         elif self.numWide==14:  # real/imaginary or mag/phase
00204             if self.thermal==0:
00205                 resultName = 'loadVectors'
00206                 self.createTransientObject(self.loadVectors,ComplexLoadVectorObject) # complex
00207                 self.handleResultsBuffer3(self.OUG_ComplexTable,resultName)
00208             else:
00209                 self.NotImplementedOrSkip()
00210         else:
00211             raise RuntimeError('only numWide=8 or 14 is allowed  numWide=%s' %(self.numWide))
00212 
00213     def readOPG_Data_table12(self): # Nonlinear Force Vector (in progress)
00214         #isSort1 = self.isSort1()
00215         if self.numWide==8:  # real/random
00216             if self.thermal==0:
00217                 resultName = 'forceVectors'
00218                 self.createTransientObject(self.forceVectors,ForceVectorObject) # real
00219                 self.handleResultsBuffer3(self.OUG_RealTable,resultName)
00220             else:
00221                 self.NotImplementedOrSkip()
00222         elif self.numWide==14:  # real/imaginary or mag/phase
00223             if self.thermal==0:
00224                 resultName = 'forceVectors'
00225                 self.createTransientObject(self.forceVectors,ComplexForceVectorObject) # complex
00226                 self.handleResultsBuffer3(self.OUG_ComplexTable,resultName)
00227             else:
00228                 self.NotImplementedOrSkip()
00229         else:
00230             raise RuntimeError('only numWide=8 or 14 is allowed  numWide=%s' %(self.numWide))
00231 
00232     def readOPG_Data_table19(self): # Applied Loads
00233         #isSort1 = self.isSort1()
00234         if self.numWide == 8:  # real/random
00235             resultName = 'appliedLoads'
00236             if self.thermal == 0:
00237                 self.createTransientObject(self.appliedLoads,AppliedLoadsObject) # real
00238                 self.handleResultsBuffer3(self.readOPGForces,resultName)
00239             else:
00240                 self.NotImplementedOrSkip()
00241         #elif self.numWide == 14:  # real/imaginary or mag/phase
00242         #    if self.thermal == 0:
00243         #        self.createTransientObject(self.appliedLoads,ComplexAppliedLoadsObject) # complex
00244         #        raise NotImplementedError('can this use a OUG_Complex table???')
00245         #    else:
00246         #        raise NotImplementedError(self.codeInformation())
00247         #    #self.handleResultsBuffer3(self.OUG_ComplexTable,resultName)
00248         #    raise NotImplementedError(self.codeInformation())
00249         else:
00250             raise RuntimeError('only numWide=8 or 14 is allowed  numWide=%s' %(self.numWide))
00251 
00252     def readOGS1_Data_table26(self): # OGS1 - grid point stresses - surface
00253         #isSort1 = self.isSort1()
00254         resultName = 'gridPointStresses'
00255         if self.numWide==11:  # real/random
00256             self.createTransientObject(self.gridPointStresses,GridPointStressesObject) # real
00257             self.handleResultsBuffer3(self.readOGS1_table26_numWide11,resultName)
00258         else:
00259             raise RuntimeError('only numWide=11 is allowed  numWide=%s' %(self.numWide))
00260 
00261     def readOGS1_table26_numWide11(self): # surface stresses
00262         dt = self.nonlinearFactor
00263         (format1,extract) = self.getOEF_FormatStart()
00264         format1 += 'i4s8f'
00265         format1 = bytes(format1)
00266 
00267         while len(self.data) >= 44:
00268             eData     = self.data[0:44]
00269             self.data = self.data[44: ] # 11*4
00270             out = unpack(format1,eData)
00271             (eKey,eid,fiber,nx,ny,txy,angle,major,minor,tmax,ovm) = out
00272             eKey = extract(eKey,dt)
00273             fiber = fiber.strip()
00274             self.obj.add(dt,eKey,eid,fiber,nx,ny,txy,angle,major,minor,tmax,ovm)
00275         #print len(self.data)
00276 
00277     def readOGS1_Data_table27(self): # OGS1 - grid point stresses - volume direct
00278         #isSort1 = self.isSort1()
00279         #print(self.codeInformation())
00280         if self.numWide == 9:  # real/random
00281             resultName = 'gridPointVolumeStresses'
00282             self.createTransientObject(self.gridPointVolumeStresses,GridPointStressesVolumeObject) # real
00283             self.handleResultsBuffer3(self.readOGS1_table27_numWide9,resultName)
00284         else:
00285             raise RuntimeError('only numWide=9 is allowed  numWide=%s' %(self.numWide))
00286 
00287     def readOGS1_table27_numWide9(self): # surface stresses
00288         dt = self.nonlinearFactor
00289         (format1,extract) = self.getOEF_FormatStart()
00290         format1 += 'i7f'
00291         format1 = bytes(format1)
00292 
00293         while len(self.data) >= 36:
00294             eData     = self.data[0:36]
00295             self.data = self.data[36: ] # 9*4
00296             out = unpack(format1,eData)
00297             (eKey,nx,ny,nz,txy,tyz,txz,pressure,ovm) = out
00298             eKey = extract(eKey,dt)
00299 
00300             self.obj.add(dt,eKey,nx,ny,nz,txy,tyz,txz,pressure,ovm)
00301         #print len(self.data)
00302 
00303 
00304     def readOPGForces(self): ## @todo needs some work...
00305         raise RuntimeError('this should never been called...')
00306         dt = self.nonlinearFactor
00307         (format1,extract) = self.getOUG_FormatStart()
00308         format1 += 'i'
00309         format1 = bytes(format1)
00310 
00311         #nTotal = self.numWide*4
00312         nTotal = 40 # same as dn
00313         while len(data)>dn:
00314             #print "len(data) = ",len(data)
00315             eData = self.data[0:dn]
00316             #self.printBlock(data[:dn])
00317             (gridDevice,eid) = unpack(format1,data[0:8])
00318             nodeID = extract(gridDevice,dt)
00319             
00320             source = unpack(b'8s',data[8:16])
00321             (dx,dy,dz,rx,ry,rz) = unpack(b'6f',data[16:40])
00322             #print "source = |%s|" %(source)
00323             
00324             #print "nodeID=%s eid=%s source=|%s| dx=%-4i dy=%-4i dz=%-4i rx=%-4i ry=%-4i rz=%-4i" %(nodeID,eid,source,dx,dy,dz,rx,ry,rz)
00325             source2 = source.replace('*','').replace('-','').strip()
00326             assert source2.isalnum(), 'source=|%s| contains invalid characters...' % (source)
00327             
00328             self.obj.add(nodeID,eid,source,dx,dy,dz,rx,ry,rz)
00329             #print "gridDevice = ",gridDevice
00330             #print "deviceCode = ",deviceCode
00331             #print "nodeID=%g dx=%g dy=%g dz=%g rx=%g ry=%g rz=%g" %(nodeID,xGrad,yGrad,zGrad,xFlux,yFlux,zFlux)
00332             self.data = self.data[dn:]
00333         ###
00334         #print "***********"
00335         #print self.obj
00336 
 All Classes Namespaces Files Functions Variables