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 #import sys 00028 from struct import unpack 00029 00030 # pyNastran 00031 from pyNastran.op2.op2_helper import polarToRealImag 00032 from .ogf_Objects import gridPointForcesObject,complexGridPointForcesObject 00033 00034 class OGF(object): 00035 """Table of Grid Point Forces""" 00036 00037 def readTable_OGF(self): 00038 table3 = self.readTable_OGF_3 00039 table4Data = self.readOGF_Data 00040 self.readResultsTable(table3,table4Data) 00041 self.deleteAttributes_OGF() 00042 00043 def deleteAttributes_OGF(self): 00044 params = ['formatCode','appCode','numWide','value1','value2',] 00045 self.deleteAttributes(params) 00046 00047 #def addDataParameter(self,data,Name,Type,FieldNum,applyNonlinearFactor=True): 00048 # #self.mode = self.getValues(data,'i',5) ## mode number 00049 # value = self.getValues(data,Type,FieldNum) 00050 # setattr(self,Name,value) 00051 # self.dataCode[Name] = value 00052 # 00053 # if applyNonlinearFactor: 00054 # self.nonlinearFactor = value 00055 # self.dataCode['nonlinearFactor'] = value 00056 # self.dataCode['name'] = Name 00057 00058 def applyDataCodeValue(self,Name,value): 00059 self.dataCode[Name] = value 00060 00061 def readTable_OGF_3(self,iTable): # iTable=-3 00062 bufferWords = self.getMarker() 00063 if self.makeOp2Debug: 00064 self.op2Debug.write('bufferWords=%s\n' %(str(bufferWords))) 00065 #print "2-bufferWords = ",bufferWords,bufferWords*4,'\n' 00066 00067 data = self.getData(4) 00068 bufferSize, = unpack(b'i',data) 00069 data = self.getData(4*50) 00070 #print self.printBlock(data) 00071 00072 (three) = self.parseApproachCode(data) 00073 00074 self.addDataParameter(data,'formatCode', 'i',9,False) ## format code 00075 self.addDataParameter(data,'appCode', 'i',9,False) ## approach code ??? 00076 self.addDataParameter(data,'numWide', 'i',10,False) ## number of words per entry in record; @note is this needed for this table ??? 00077 self.addDataParameter(data,'value1', 'i',11,False) ## Data Value 1 00078 self.addDataParameter(data,'value2', 'f',12,False) ## Data Value 2 00079 00080 #self.printBlock(data) # on 00081 ## assuming tCode=1 00082 if self.analysisCode==1: # statics / displacement / heat flux 00083 #self.extractDt = self.extractInt 00084 self.applyDataCodeValue('dataNames',['lsdvmn']) 00085 self.setNullNonlinearFactor() 00086 elif self.analysisCode==2: # real eigenvalues 00087 self.addDataParameter(data,'mode','i',5) ## mode number 00088 self.applyDataCodeValue('dataNames',['mode']) 00089 #elif self.analysisCode==3: # differential stiffness 00090 #self.lsdvmn = self.getValues(data,'i',5) ## load set number 00091 #self.extractDt = self.extractInt 00092 #elif self.analysisCode==4: # differential stiffness 00093 #self.extractDt = self.extractInt 00094 elif self.analysisCode==5: # frequency 00095 self.addDataParameter(data,'freq','f',5) ## frequency 00096 self.applyDataCodeValue('dataNames',['freq']) 00097 elif self.analysisCode==6: # transient 00098 self.addDataParameter(data,'time','f',5) ## time step 00099 self.applyDataCodeValue('dataNames',['time']) 00100 #elif self.analysisCode==7: # pre-buckling 00101 #self.extractDt = self.extractInt 00102 #self.applyDataCodeValue('dataNames',['lsdvmn']) 00103 #elif self.analysisCode==8: # post-buckling 00104 #self.extractDt = self.extractInt 00105 #self.applyDataCodeValue('dataNames',['lsdvmn','eigr']) 00106 elif self.analysisCode==9: # complex eigenvalues 00107 self.addDataParameter(data,'mode','i',5) ## mode number 00108 #self.addDataParameter(data,'eigr','f',6,False) ## real eigenvalue 00109 self.applyDataCodeValue('dataNames',['mode','eigr','eigi']) 00110 elif self.analysisCode==10: # nonlinear statics 00111 self.addDataParameter(data,'loadFactor','f',5) ## load factor 00112 self.applyDataCodeValue('dataNames',['loadFactor']) 00113 #elif self.analysisCode==11: # old geometric nonlinear statics 00114 #self.extractDt = self.extractInt 00115 #self.applyDataCodeValue('dataNames',['lsdvmn']) 00116 elif self.analysisCode==12: # contran ? (may appear as aCode=6) --> straight from DMAP...grrr... 00117 self.addDataParameter(data,'time','f',5) ## time step 00118 self.applyDataCodeValue('dataNames',['time']) 00119 #self.extractDt = self.extractInt 00120 #self.applyDataCodeValue('dataNames',['lsdvmn']) 00121 else: 00122 raise RuntimeError('invalid analysisCode...analysisCode=%s' %(self.analysisCode)) 00123 00124 00125 #print "*iSubcase=%s"%(self.iSubcase) 00126 #print "analysisCode=%s tableCode=%s thermal=%s" %(self.analysisCode,self.tableCode,self.thermal) 00127 00128 if not self.isSort1(): 00129 raise NotImplementedError('sort2...') 00130 00131 #self.printBlock(data) 00132 self.readTitle() 00133 00134 def readOGF_Data(self): 00135 #print "self.analysisCode=%s tableCode(1)=%s thermal(23)=%g" %(self.analysisCode,self.tableCode,self.thermal) 00136 #tfsCode = [self.tableCode,self.formatCode,self.sortCode] 00137 #print self.dataCode 00138 #print "tfsCode=%s" %(tfsCode) 00139 00140 if self.tableCode==19: # grid point forces 00141 assert self.tableName in ['OGPFB1'],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode) 00142 self.readOGF_Data_table19() 00143 else: 00144 #self.log.debug('skipping approach/table/format/sortCode=%s on %s-OGF table' %(self.tableName,self.atfsCode)) 00145 self.NotImplementedOrSkip('bad approach/table/format/sortCode=%s on %s-OGF table' %(self.atfsCode,self.tableName)) 00146 ### 00147 #print self.obj 00148 00149 00150 def readOGF_Data_table19(self): # grid point forces 00151 #isSort1 = self.isSort1() 00152 if self.numWide==10: # real/random 00153 #if self.thermal==0: 00154 self.createTransientObject(self.gridPointForces,gridPointForcesObject) # real 00155 self.handleResultsBuffer3(self.readOGF_numWide10,resultName='gridPointForces') 00156 #else: 00157 #self.NotImplementedOrSkip() 00158 #self.handleResultsBuffer3(self.OUG_RealTable) 00159 elif self.numWide==16: # real/imaginary or mag/phase 00160 #if self.thermal==0: 00161 self.createTransientObject(self.gridPointForces,complexGridPointForcesObject) # complex 00162 self.handleResultsBuffer3(self.readOGF_numWide16,resultName='gridPointForces') 00163 #else: 00164 #self.NotImplementedOrSkip() 00165 #self.handleResultsBuffer3(self.OUG_ComplexTable) 00166 else: 00167 raise NotImplementedError('only numWide=10 or 16 is allowed numWide=%s' %(self.numWide)) 00168 ### 00169 00170 def readOGF_numWide10(self): 00171 dt = self.nonlinearFactor 00172 (format1,extract) = self.getOEF_FormatStart() 00173 format1 += 'i8s6f' 00174 format1 = bytes(format1) 00175 00176 while len(self.data) >= 40: 00177 eData = self.data[0:4*10] 00178 self.data = self.data[4*10: ] 00179 out = unpack(format1,eData) 00180 (eKey,eid,elemName,f1,f2,f3,m1,m2,m3) = out 00181 eKey = extract(eKey,dt) 00182 elemName = elemName.strip() 00183 #data = (eid,elemName,f1,f2,f3,m1,m2,m3) 00184 self.obj.add(dt,eKey,eid,elemName,f1,f2,f3,m1,m2,m3) 00185 #print "eid/dt/freq=%s eid=%-6s eName=%-8s f1=%g f2=%g f3=%g m1=%g m2=%g m3=%g" %(ekey,eid,elemName,f1,f2,f3,m1,m2,m3) 00186 #print len(self.data) 00187 00188 def readOGF_numWide16(self): 00189 dt = self.nonlinearFactor 00190 (format1,extract) = self.getOEF_FormatStart() 00191 format1 += 'i8s12f' 00192 format1 = bytes(format1) 00193 isMagnitudePhase = self.isMagnitudePhase() 00194 00195 while len(self.data)>=64: 00196 eData = self.data[0:4*16] 00197 self.data = self.data[4*16: ] 00198 out = unpack(format1,eData) 00199 (eKey,eid,elemName,f1r,f2r,f3r,m1r,m2r,m3r,f1i,f2i,f3i,m1i,m2i,m3i) = out 00200 eKey = extract(eKey,dt) 00201 00202 if isMagnitudePhase: 00203 f1 = polarToRealImag(f1r,f1i); m1 = polarToRealImag(m1r,m1i) 00204 f2 = polarToRealImag(f2r,f2i); m2 = polarToRealImag(m2r,m2i) 00205 f3 = polarToRealImag(f3r,f3i); m3 = polarToRealImag(m3r,m3i) 00206 else: 00207 f1 = complex(f1r,f1i); m1 = complex(m1r,m1i) 00208 f2 = complex(f2r,f2i); m2 = complex(m2r,m2i) 00209 f3 = complex(f3r,f3i); m3 = complex(m3r,m3i) 00210 00211 elemName = elemName.strip() 00212 #print "eid/dt/freq=%s eid=%-6s eName=%-8s f1=%s f2=%s f3=%s m1=%s m2=%s m3=%s" %(ekey,eid,elemName,f1r+f1i,f2r+f2i,f3r+f3i,m1r+m1i,m2r+m2i,m3r+m3i) 00213 self.obj.add(dt,eKey,eid,elemName,f1,f2,f3,m1,m2,m3) 00214 00215 def readThermal4(self): 00216 #print self.codeInformation() 00217 #print self.printBlock(self.data) 00218 n = 0 00219 nEntries = len(self.data)//32 00220 for i in xrange(nEntries): 00221 eData = self.data[n:n+32] 00222 out = unpack(b'2i6f', eData) 00223 #nid = (out[0]-self.deviceCode)//10 ## @todo update... 00224 #print out 00225 n+=32 00226 #print "nid = ",nid