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 #from struct import pack 00026 from numpy import array #,abs,angle 00027 00028 from pyNastran.op2.resultObjects.op2_Objects import scalarObject 00029 from pyNastran.op2.resultObjects.tableObject import TableObject,ComplexTableObject 00030 00031 class EigenVectorObject(TableObject): # approachCode=2, sortCode=0, thermal=0 00032 """ 00033 EIGENVALUE = 6.158494E+07 00034 CYCLES = 1.248985E+03 R E A L E I G E N V E C T O R N O . 1 00035 00036 POINT ID. TYPE T1 T2 T3 R1 R2 R3 00037 1 G 2.547245E-17 -6.388945E-16 2.292728E+00 -1.076928E-15 2.579163E-17 0.0 00038 2002 G -6.382321E-17 -1.556607E-15 3.242408E+00 -6.530917E-16 1.747180E-17 0.0 00039 2003 G 0.0 0.0 0.0 0.0 0.0 0.0 00040 """ 00041 def __init__(self,dataCode,isSort1,iSubcase,iMode): 00042 TableObject.__init__(self,dataCode,isSort1,iSubcase,iMode) 00043 #self.caseVal = mode 00044 self.updateDt = self.updateMode 00045 #print "mode = %s" %(mode) 00046 #print "dataCode = ",self.dataCode 00047 self.setDataMembers() 00048 00049 #assert mode>=0. 00050 self.gridTypes = {} 00051 #self.translations = {iMode: {}} 00052 #self.rotations = {iMode: {}} 00053 00054 def readF06Data(self,dataCode, data): 00055 iMode = dataCode['mode'] 00056 if iMode not in self.translations: 00057 self.updateMode(dataCode, iMode) 00058 00059 for line in data: 00060 (nid,gridType,t1,t2,t3,r1,r2,r3) = line 00061 self.gridTypes[nid] = gridType 00062 self.translations[iMode][nid] = array([t1,t2,t3]) 00063 self.rotations[iMode][nid] = array([r1,r2,r3]) 00064 ### 00065 00066 def updateMode(self, dataCode, iMode): 00067 """ 00068 this method is called if the object 00069 already exits and a new time step is found 00070 """ 00071 #assert mode>=0. 00072 self.dataCode = dataCode 00073 self.applyDataCode() 00074 #self.caseVal = iMode 00075 #print "mode = %s" %(str(mode)) 00076 self.addNewMode(iMode) 00077 self.setDataMembers() 00078 00079 def addNewMode(self,iMode): 00080 self.translations[iMode] = {} 00081 self.rotations[iMode] = {} 00082 00083 def eigenvalues(self): 00084 return self.eigrs 00085 00086 def writeMatlab(self,iSubcase,f=None,isMagPhase=False): 00087 name = 'eigenvectors' 00088 return self._writeMatlabTransient(name,iSubcase,f,isMagPhase) 00089 00090 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00091 """ 00092 EIGENVALUE = 6.158494E+07 00093 CYCLES = 1.248985E+03 R E A L E I G E N V E C T O R N O . 1 00094 00095 POINT ID. TYPE T1 T2 T3 R1 R2 R3 00096 1 G 2.547245E-17 -6.388945E-16 2.292728E+00 -1.076928E-15 2.579163E-17 0.0 00097 2002 G -6.382321E-17 -1.556607E-15 3.242408E+00 -6.530917E-16 1.747180E-17 0.0 00098 2003 G 0.0 0.0 0.0 0.0 0.0 0.0 00099 """ 00100 msg = [] 00101 hasCycle = hasattr(self, 'modeCycle') 00102 00103 for i,(iMode,eigVals) in enumerate(sorted(self.translations.iteritems())): 00104 msg += header 00105 freq = self.eigrs[i] 00106 msg.append('%16s = %13E\n' %('EIGENVALUE',freq)) 00107 00108 if hasCycle: 00109 msg.append('%16s = %13E R E A L E I G E N V E C T O R N O . %10i\n \n' %('CYCLES',self.modeCycle,iMode)) 00110 else: 00111 msg.append(' R E A L E I G E N V E C T O R N O . %10i\n \n' %(iMode)) 00112 00113 msg.append(' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n') 00114 for nodeID,displacement in sorted(eigVals.iteritems()): 00115 rotation = self.rotations[iMode][nodeID] 00116 gridType = self.gridTypes[nodeID] 00117 (dx,dy,dz) = displacement 00118 (rx,ry,rz) = rotation 00119 00120 vals = [dx,dy,dz,rx,ry,rz] 00121 (vals2,isAllZeros) = self.writeFloats13E(vals) 00122 [dx,dy,dz,rx,ry,rz] = vals2 00123 msg.append('%14i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dx,dy,dz,rx,ry,rz.rstrip())) 00124 ### 00125 msg.append(pageStamp+str(pageNum)+'\n') 00126 if f is not None: 00127 f.write(''.join(msg)) 00128 msg = [''] 00129 pageNum += 1 00130 ### 00131 return (''.join(msg),pageNum-1) 00132 00133 def __repr__(self): 00134 msg = '---EIGENVECTORS---\n' 00135 msg += self.printDataMembers() 00136 name = self.dataCode['name'] 00137 00138 headers = ['Tx','Ty','Tz','Rx','Ry','Rz'] 00139 headerLine = '%-8s %8s ' %('nodeID','GridType',) 00140 for header in headers: 00141 headerLine += '%10s ' %(header) 00142 headerLine += '\n' 00143 00144 for i,(iMode,eigVals) in enumerate(sorted(self.translations.iteritems())): 00145 freq = self.eigrs[i] 00146 msg += '%s = %g\n' %(name,iMode) 00147 msg += 'eigenvalueReal = %g\n' %(freq) 00148 #msg += 'eigenvalueReal = %f\n' %(freq) 00149 msg += headerLine 00150 for nodeID,displacement in sorted(eigVals.iteritems()): 00151 rotation = self.rotations[iMode][nodeID] 00152 gridType = self.gridTypes[nodeID] 00153 (dx,dy,dz) = displacement 00154 (rx,ry,rz) = rotation 00155 00156 msg += '%-8i %8s ' %(nodeID,gridType) 00157 vals = [dx,dy,dz,rx,ry,rz] 00158 for val in vals: 00159 if abs(val)<1e-6: 00160 msg += '%10s ' %(0) 00161 else: 00162 msg += '%10.3g ' %(val) 00163 ### 00164 msg += '\n' 00165 ### 00166 msg += '\n' 00167 #print msg 00168 #return msg 00169 return msg 00170 00171 class realEigenVectorObject(scalarObject): # approachCode=2, sortCode=0, thermal=0 00172 """ 00173 R E A L E I G E N V E C T O R N O . 1 00174 POINT ID. TYPE T1 T2 T3 R1 R2 R3 00175 1 G 0.0 0.0 0.0 0.0 1.260264E-01 0.0 00176 7 G 9.999849E-01 0.0 6.728968E-03 0.0 8.021386E-03 0.0 00177 """ 00178 def __init__(self,dataCode,iSubcase,iMode): 00179 scalarObject.__init__(self,dataCode,iSubcase) 00180 #self.caseVal = mode 00181 #print "mode = %s" %(iMode) 00182 self.caseVal = self.getUnsteadyValue() 00183 self.setDataMembers() 00184 00185 #assert mode>=0. 00186 self.gridTypes = {} 00187 self.translations = {iMode: {}} 00188 self.rotations = {iMode: {}} 00189 00190 def addNewMode(self,iMode): 00191 self.translations[iMode] = {} 00192 self.rotations[iMode] = {} 00193 00194 def updateDt(self,dataCode,dt): 00195 #print " self.dataCode = ",self.dataCode 00196 self.dataCode = dataCode 00197 self.applyDataCode() 00198 self.setDataMembers() 00199 self.caseVal = dt 00200 00201 #print "*self.dataCode = ",self.dataCode 00202 self.translations[self.caseVal] = {} 00203 self.rotations[self.caseVal] = {} 00204 00205 def deleteTransient(self,dt): 00206 del self.translations[dt] 00207 del self.rotations[dt] 00208 00209 def getTransients(self): 00210 k = self.translations.keys() 00211 k.sort() 00212 return k 00213 00214 def add(self,nodeID,gridType,v1,v2,v3,v4,v5,v6): 00215 msg = "nodeID=%s v1=%s v2=%s v3=%s" %(nodeID,v1,v2,v3) 00216 msg += " v4=%s v5=%s v6=%s" %(v4,v5,v6) 00217 #print msg 00218 assert 0<nodeID<1000000000, msg 00219 #assert nodeID not in self.translations 00220 00221 if gridType==1: 00222 Type = 'G' 00223 elif gridType==2: 00224 Type = 'S' 00225 elif gridType==7: 00226 Type = 'L' 00227 else: 00228 raise ValueError('invalid grid type...gridType=%s' %(gridType)) 00229 00230 self.gridTypes[nodeID] = Type 00231 #print 'self.caseVal = %s' %(self.caseVal),type(self.caseVal) 00232 #print "d = ",self.translations 00233 self.translations[self.caseVal][nodeID] = [v1,v2,v3] 00234 self.rotations[self.caseVal][nodeID] = [v4,v5,v6] 00235 ### 00236 00237 def modes(self): 00238 return sorted(self.translations.keys()) 00239 00240 def eigenvalues(self): 00241 return self.eigrs 00242 00243 def writeMatlab(self,iSubcase,f=None,isMagPhase=False): 00244 name = 'eigenvectors' 00245 return self._writeMatlabTransient(name,iSubcase,f,isMagPhase) 00246 00247 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00248 """ 00249 EIGENVALUE = 6.158494E+07 00250 R E A L E I G E N V E C T O R N O . 1 00251 00252 POINT ID. TYPE T1 T2 T3 R1 R2 R3 00253 1 G 2.547245E-17 -6.388945E-16 2.292728E+00 -1.076928E-15 2.579163E-17 0.0 00254 2002 G -6.382321E-17 -1.556607E-15 3.242408E+00 -6.530917E-16 1.747180E-17 0.0 00255 2003 G 0.0 0.0 0.0 0.0 0.0 0.0 00256 """ 00257 msg = [] 00258 #print self.dataCode 00259 for i,(iMode,eigVals) in enumerate(sorted(self.translations.iteritems())): 00260 msg += header 00261 freq = self.eigrs[i] 00262 msg.append('%16s = %12E\n' %('EIGENVALUE',freq)) 00263 msg.append(' R E A L E I G E N V E C T O R N O . %10i\n \n' %(iMode)) 00264 msg.append(' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n') 00265 for nodeID,translation in sorted(eigVals.iteritems()): 00266 rotation = self.rotations[iMode][nodeID] 00267 gridType = self.gridTypes[nodeID] 00268 (dx,dy,dz) = translation 00269 (rx,ry,rz) = rotation 00270 00271 vals = [dx,dy,dz,rx,ry,rz] 00272 (vals2,isAllZeros) = self.writeFloats13E(vals) 00273 [dx,dy,dz,rx,ry,rz] = vals2 00274 msg.append('%14i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dx,dy,dz,rx,ry,rz.rstrip())) 00275 ### 00276 msg.append(pageStamp+str(pageNum)+'\n') 00277 pageNum += 1 00278 ### 00279 return (''.join(msg),pageNum-1) 00280 00281 def __repr__(self): 00282 msg = '---REAL EIGENVECTORS---\n' 00283 msg += self.printDataMembers() 00284 name = self.dataCode['name'] 00285 00286 headers = ['T'] 00287 headerLine = '%-8s %8s ' %('nodeID','GridType',) 00288 for header in headers: 00289 headerLine += '%10s ' %(header) 00290 headerLine += '\n' 00291 00292 for iMode,eigVals in sorted(self.translations.iteritems()): 00293 msg += '%s = %s\n' %(name,iMode) 00294 msg += headerLine 00295 for nodeID,translation in sorted(eigVals.iteritems()): 00296 Type = self.gridTypes[nodeID] 00297 00298 rotation = self.rotations[iMode][nodeID] 00299 (dx,dy,dz) = translation 00300 (rx,ry,rz) = rotation 00301 00302 vals = [dx,dy,dz,rx,ry,rz] 00303 msg += '%-8i %8s ' %(nodeID,Type) 00304 for v in vals: 00305 if abs(v)<1e-6: 00306 msg += '%10s ' %(0) 00307 else: 00308 msg += '%10.3f ' %(v) 00309 ### 00310 ### 00311 msg += '\n' 00312 ### 00313 msg += '\n' 00314 return msg 00315 00316 class ComplexEigenVectorObject(ComplexTableObject): # approachCode=2, sortCode=0, thermal=0 00317 def __init__(self,dataCode,isSort1,iSubcase,iMode): 00318 ComplexTableObject.__init__(self,dataCode,isSort1,iSubcase,iMode) 00319 self.caseVal = iMode 00320 self.updateDt = self.updateMode 00321 self.setDataMembers() 00322 00323 #print "mode = %s" %(mode) 00324 00325 #assert mode>=0. 00326 #self.gridTypes = {} 00327 #self.translations = {iMode: {}} 00328 #self.rotations = {iMode: {}} 00329 00330 def updateMode(self,dataCode,iMode): 00331 """ 00332 this method is called if the object 00333 already exits and a new time step is found 00334 """ 00335 #assert mode>=0. 00336 self.caseVal = iMode 00337 self.dataCode = dataCode 00338 self.applyDataCode() 00339 self.setDataMembers() 00340 #print "mode = %s" %(str(mode)) 00341 self.addNewMode(iMode) 00342 00343 def addNewMode(self,iMode): 00344 self.translations[iMode] = {} 00345 self.rotations[iMode] = {} 00346 00347 def eigenvalues(self): 00348 return sorted(self.translations.keys()) 00349 00350 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00351 msg = [] 00352 #print self.dataCode 00353 hasCycle = hasattr(self, 'modeCycle') 00354 for i,(iMode,eigVals) in enumerate(sorted(self.translations.iteritems())): 00355 msg += header 00356 freq = self.eigrs[i] 00357 #freq = 0.0 00358 msg.append('%16s = %12E\n' %('EIGENVALUE',freq)) 00359 if hasCycle: 00360 msg.append('%16s = %12E C O M P L E X E I G E N V E C T O R N O . %10i\n \n' %('CYCLES',self.modeCycle,iMode)) 00361 else: 00362 msg.append(' C O M P L E X E I G E N V E C T O R N O . %10i\n \n' %(iMode)) 00363 msg.append(' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n') 00364 for nodeID,displacement in sorted(eigVals.iteritems()): 00365 rotation = self.rotations[iMode][nodeID] 00366 gridType = self.gridTypes[nodeID] 00367 (dx,dy,dz) = displacement 00368 (rx,ry,rz) = rotation 00369 00370 vals = [dx,dy,dz,rx,ry,rz] 00371 (vals2,isAllZeros) = self.writeImagFloats13E(vals,isMagPhase) 00372 [dxr,dyr,dzr,rxr,ryr,rzr,dxi,dyi,dzi,rxi,ryi,rzi] = vals2 00373 00374 msg.append('%14i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dxr,dyr,dzr,rxr,ryr,rzr.rstrip())) 00375 msg.append('%14s %6s %13s %13s %13s %13s %13s %-s\n' %('','', dxi,dyi,dzi,rxi,ryi,rzi.rstrip())) 00376 ### 00377 msg.append(pageStamp+str(pageNum)+'\n') 00378 if f is not None: 00379 f.write(''.join(msg)) 00380 msg = [''] 00381 pageNum += 1 00382 ### 00383 return (''.join(msg),pageNum-1) 00384 00385 def __repr__(self): 00386 msg = '---EIGENVECTORS---\n' 00387 msg += self.printDataMembers() 00388 00389 headers = ['T1','T2','T3','R1','R2','R3'] 00390 headerLine = '%-8s %8s ' %('nodeID','GridType',) 00391 for header in headers: 00392 headerLine += '%10s ' %(header) 00393 headerLine += '\n' 00394 name = self.dataCode['name'] 00395 00396 for i,(iMode,eigVals) in enumerate(sorted(self.translations.iteritems())): 00397 msg += '%s = %g\n' %(name,iMode) 00398 msg += headerLine 00399 for nodeID,translation in sorted(eigVals.iteritems()): 00400 rotation = self.rotations[iMode][nodeID] 00401 Type = self.gridTypes[nodeID] 00402 #(dx,dy,dz) = displacement 00403 #(rx,ry,rz) = rotation 00404 00405 msg += '%-8i %8s ' %(nodeID,Type) 00406 vals = translation+rotation 00407 for val in vals: 00408 if abs(val)<1e-6: 00409 msg += '%10s ' %(0) 00410 else: 00411 msg += '%10s ' %(str(val)) 00412 #msg += '%10.3g ' %(val) 00413 ### 00414 msg += '\n' 00415 ### 00416 msg += '\n' 00417 return msg 00418