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 import sys 00026 from pyNastran.op2.resultObjects.tableObject import TableObject,ComplexTableObject 00027 00028 class LoadVectorObject(TableObject): # tableCode=2, sortCode=0, thermal=0 00029 def __init__(self,dataCode,isSort1,iSubcase,dt=None): 00030 TableObject.__init__(self,dataCode,isSort1,iSubcase,dt) 00031 00032 def writeMatlab(self,iSubcase,f=None,isMagPhase=False): 00033 name = 'loadVector' 00034 if self.nonlinearFactor is None: 00035 return self._writeMatlab(name,iSubcase,f) 00036 else: 00037 return self._writeMatlabTransient(name,iSubcase,f) 00038 00039 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00040 if self.nonlinearFactor is not None: 00041 return self.writeF06Transient(header,pageStamp,pageNum,f) 00042 00043 msg = header+[' L O A D V E C T O R\n', 00044 ' \n', 00045 ' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n'] 00046 for nodeID,translation in sorted(self.translations.iteritems()): 00047 rotation = self.rotations[nodeID] 00048 gridType = self.gridTypes[nodeID] 00049 00050 (dx,dy,dz) = translation 00051 (rx,ry,rz) = rotation 00052 vals = [dx,dy,dz,rx,ry,rz] 00053 (vals2,isAllZeros) = self.writeFloats13E(vals) 00054 if not isAllZeros: 00055 [dx,dy,dz,rx,ry,rz] = vals2 00056 msg.append('%14i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dx,dy,dz,rx,ry,rz.rstrip())) 00057 ### 00058 ### 00059 msg.append(pageStamp+str(pageNum)+'\n') 00060 if f is not None: 00061 f.write(''.join(msg)) 00062 msg = [''] 00063 return (''.join(msg),pageNum) 00064 00065 def writeF06Transient(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00066 msg = [] 00067 words = [' L O A D V E C T O R\n', 00068 ' \n', 00069 ' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n'] 00070 00071 for dt,translations in sorted(self.translations.iteritems()): 00072 header[1] = ' %s = %10.4E\n' %(self.dataCode['name'],dt) 00073 msg += header+words 00074 for nodeID,translation in sorted(translations.iteritems()): 00075 rotation = self.rotations[dt][nodeID] 00076 gridType = self.gridTypes[nodeID] 00077 00078 (dx,dy,dz) = translation 00079 (rx,ry,rz) = rotation 00080 00081 vals = [dx,dy,dz,rx,ry,rz] 00082 (vals2,isAllZeros) = self.writeFloats13E(vals) 00083 if not isAllZeros: 00084 [dx,dy,dz,rx,ry,rz] = vals2 00085 msg.append('%14i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dx,dy,dz,rx,ry,rz.rstrip())) 00086 ### 00087 ### 00088 msg.append(pageStamp+str(pageNum)+'\n') 00089 if f is not None: 00090 f.write(''.join(msg)) 00091 msg = [''] 00092 pageNum+=1 00093 return (''.join(msg),pageNum-1) 00094 00095 def __reprTransient__(self): 00096 msg = '---TRANSIENT LOAD VECTOR---\n' 00097 #msg += '%s = %g\n' %(self.dataCode['name'],self.dt) 00098 msg += self.writeHeader() 00099 00100 for dt,translations in sorted(self.translations.iteritems()): 00101 msg += '%s = %g\n' %(self.dataCode['name'],dt) 00102 for nodeID,translation in sorted(translations.iteritems()): 00103 rotation = self.rotations[dt][nodeID] 00104 gridType = self.gridTypes[nodeID] 00105 (dx,dy,dz) = translation 00106 (rx,ry,rz) = rotation 00107 00108 msg += '%-10i %8s ' %(nodeID,gridType) 00109 vals = [dx,dy,dz,rx,ry,rz] 00110 for val in vals: 00111 if abs(val)<1e-6: 00112 msg += '%10s ' %(0) 00113 else: 00114 msg += '%10.3e ' %(val) 00115 ### 00116 msg += '\n' 00117 ### 00118 return msg 00119 00120 def __repr__(self): 00121 if self.nonlinearFactor is not None: 00122 return self.__reprTransient__() 00123 00124 msg = '---LOAD VECTOR---\n' 00125 msg += self.writeHeader() 00126 00127 for nodeID,translation in sorted(self.translations.iteritems()): 00128 rotation = self.rotations[nodeID] 00129 gridType = self.gridTypes[nodeID] 00130 00131 (dx,dy,dz) = translation 00132 (rx,ry,rz) = rotation 00133 00134 msg += '%-10i %-8s ' %(nodeID,gridType) 00135 vals = [dx,dy,dz,rx,ry,rz] 00136 for val in vals: 00137 if abs(val)<1e-6: 00138 msg += '%10s ' %(0) 00139 else: 00140 msg += '%10.3e ' %(val) 00141 ### 00142 msg += '\n' 00143 return msg 00144 00145 def __reprTransient__(self): 00146 return self.writeF06Transient(['',''],'PAGE ',1)[0] 00147 00148 class ComplexLoadVectorObject(ComplexTableObject): # tableCode=11, approachCode=??? 00149 def __init__(self,dataCode,isSort1,iSubcase,dt): 00150 ComplexTableObject.__init__(self,dataCode,isSort1,iSubcase,dt) 00151 00152 def writeMatlab(self,iSubcase,f=None,isMagPhase=False): 00153 name = 'loadVector' 00154 if self.nonlinearFactor is None: 00155 return self._writeMatlab(name,iSubcase,f,isMagPhase) 00156 else: 00157 return self._writeMatlabTransient(name,iSubcase,f,isMagPhase) 00158 00159 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00160 if self.nonlinearFactor is not None: 00161 return self.writeF06Transient(header,pageStamp,pageNum,f,isMagPhase) 00162 msg = header+[' C O M P L E X L O A D V E C T O R\n', 00163 ' (REAL/IMAGINARY)\n', 00164 ' \n', 00165 ' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n'] 00166 for nodeID,translation in sorted(self.translations.iteritems()): 00167 rotation = self.rotations[nodeID] 00168 gridType = self.gridTypes[nodeID] 00169 00170 (dx,dy,dz) = translation 00171 (rx,ry,rz) = rotation 00172 00173 if isMagPhase: 00174 dxr=abs(dx); dxi=angle(dx,deg=True) 00175 dyr=abs(dy); dyi=angle(dy,deg=True) 00176 dzr=abs(dz); dzi=angle(dz,deg=True) 00177 00178 rxr=abs(rx); rxi=angle(rx,deg=True) 00179 ryr=abs(ry); ryi=angle(ry,deg=True) 00180 rzr=abs(rz); rzi=angle(rz,deg=True) 00181 else: 00182 dxr=dx.real; dyr=dy.real; dzr=dz.real; 00183 dxi=dx.imag; dyi=dy.imag; dzi=dz.imag 00184 00185 rxr=rx.real; ryr=ry.real; rzr=rz.real 00186 rxi=rx.imag; ryi=ry.imag; rzi=rz.imag 00187 00188 vals = [dxr,dyr,dzr,rxr,ryr,rzr,dxi,dyi,dzi,rxi,ryi,rzi] 00189 (vals2,isAllZeros) = self.writeFloats13E(vals) 00190 [dxr,dyr,dzr,rxr,ryr,rzr,dxi,dyi,dzi,rxi,ryi,rzi] = vals2 00191 msg.append('0 %12i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dxr,dyr,dzr,rxr,ryr,rzr.rstrip())) 00192 msg.append(' %12s %6s %13s %13s %13s %13s %13s %-s\n' %('','', dxi,dyi,dzi,rxi,ryi,rzi.rstrip())) 00193 ### 00194 msg.append(pageStamp+str(pageNum)+'\n') 00195 if f is not None: 00196 f.write(''.join(msg)) 00197 msg = [''] 00198 return (''.join(msg),pageNum) 00199 00200 def writeF06Transient(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00201 words = [' C O M P L E X L O A D V E C T O R\n', 00202 ' (REAL/IMAGINARY)\n', 00203 ' \n', 00204 ' POINT ID. TYPE T1 T2 T3 R1 R2 R3\n'] 00205 #return self._writeF06TransientBlock(words,header,pageStamp,pageNum,f,isMagPhase) 00206 msg = [] 00207 for dt,translations in sorted(self.translations.iteritems()): 00208 header[2] = ' %s = %10.4E\n' %(self.dataCode['name'],dt) 00209 msg += header+words 00210 for nodeID,translation in sorted(translations.iteritems()): 00211 rotation = self.rotations[dt][nodeID] 00212 gridType = self.gridTypes[nodeID] 00213 00214 (dx,dy,dz) = translation 00215 (rx,ry,rz) = rotation 00216 00217 if isMagPhase: 00218 dxr=abs(dx); dxi=angle(dx,deg=True) 00219 dyr=abs(dy); dyi=angle(dy,deg=True) 00220 dzr=abs(dz); dzi=angle(dz,deg=True) 00221 00222 rxr=abs(rx); rxi=angle(rx,deg=True) 00223 ryr=abs(ry); ryi=angle(ry,deg=True) 00224 rzr=abs(rz); rzi=angle(rz,deg=True) 00225 else: 00226 dxr=dx.real; dyr=dy.real; dzr=dz.real; 00227 dxi=dx.imag; dyi=dy.imag; dzi=dz.imag 00228 00229 rxr=rx.real; ryr=ry.real; rzr=rz.real 00230 rxi=rx.imag; ryi=ry.imag; rzi=rz.imag 00231 00232 vals = [dxr,dyr,dzr,rxr,ryr,rzr,dxi,dyi,dzi,rxi,ryi,rzi] 00233 (vals2,isAllZeros) = self.writeFloats13E(vals) 00234 [dxr,dyr,dzr,rxr,ryr,rzr,dxi,dyi,dzi,rxi,ryi,rzi] = vals2 00235 if not isAllZeros: 00236 msg.append('0 %12i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dxr,dyr,dzr,rxr,ryr,rzr.rstrip())) 00237 msg.append(' %12s %6s %13s %13s %13s %13s %13s %-s\n' %('','', dxi,dyi,dzi,rxi,ryi,rzi.rstrip())) 00238 ### 00239 msg.append(pageStamp+str(pageNum)+'\n') 00240 if f is not None: 00241 f.write(''.join(msg)) 00242 msg = [''] 00243 pageNum+=1 00244 return (''.join(msg),pageNum-1) 00245 00246 def __repr__(self): 00247 return self.writeF06(['','',''],'PAGE ',1)[0] 00248 00249 msg = '---COMPLEX LOAD VECTOR---\n' 00250 #if self.dt is not None: 00251 # msg += '%s = %g\n' %(self.dataCode['name'],self.dt) 00252 headers = ['DxReal','DxImag','DyReal','DyImag','DzReal','DyImag','RxReal','RxImag','RyReal','RyImag','RzReal','RzImag'] 00253 msg += '%-10s ' %('nodeID') 00254 for header in headers: 00255 msg += '%10s ' %(header) 00256 msg += '\n' 00257 00258 for freq,translations in sorted(self.translations.iteritems()): 00259 msg += '%s = %g\n' %(self.dataCode['name'],dt) 00260 00261 for nodeID,translation in sorted(translations.iteritems()): 00262 rotation = self.rotations[freq][nodeID] 00263 00264 msg += '%-10i ' %(nodeID) 00265 vals = translation+rotation 00266 for val in vals: 00267 if abs(val)<1e-6: 00268 msg += '%10s ' %(0) 00269 else: 00270 msg += '%10.3e ' %(val) 00271 ### 00272 msg += '\n' 00273 ### 00274 return msg 00275 00276 class ThermalVector(TableObject): 00277 def __init__(self,dataCode,isSort1,iSubcase,dt=None): 00278 TableObject.__init__(self,dataCode,isSort1,iSubcase,dt) 00279 00280 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00281 if self.nonlinearFactor is not None: 00282 return self.writeF06Transient(header,pageStamp,pageNum,f) 00283 00284 msg = header+[' T E M P E R A T U R E V E C T O R\n', 00285 ' \n', 00286 ' POINT ID. TYPE ID VALUE ID+1 VALUE ID+2 VALUE ID+3 VALUE ID+4 VALUE ID+5 VALUE\n'] 00287 for nodeID,translation in sorted(self.translations.iteritems()): 00288 rotation = self.rotations[nodeID] 00289 gridType = self.gridTypes[nodeID] 00290 00291 (dx,dy,dz) = translation 00292 (rx,ry,rz) = rotation 00293 vals = [dx,dy,dz,rx,ry,rz] 00294 (vals2,isAllZeros) = self.writeFloats13E(vals) 00295 if not isAllZeros: 00296 [dx,dy,dz,rx,ry,rz] = vals2 00297 msg.append('%14i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dx,dy,dz,rx,ry,rz.rstrip())) 00298 ### 00299 ### 00300 msg.append(pageStamp+str(pageNum)+'\n') 00301 if f is not None: 00302 f.write(''.join(msg)) 00303 msg = [''] 00304 return (''.join(msg),pageNum) 00305 00306 def writeF06Transient(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00307 msg = [] 00308 words = [' T E M P E R A T U R E V E C T O R\n', 00309 ' \n', 00310 ' POINT ID. TYPE ID VALUE ID+1 VALUE ID+2 VALUE ID+3 VALUE ID+4 VALUE ID+5 VALUE\n'] 00311 00312 for dt,translations in sorted(self.translations.iteritems()): 00313 header[1] = ' %s = %10.4E\n' %(self.dataCode['name'],dt) 00314 msg += header+words 00315 for nodeID,translation in sorted(translations.iteritems()): 00316 rotation = self.rotations[dt][nodeID] 00317 gridType = self.gridTypes[nodeID] 00318 00319 (dx,dy,dz) = translation 00320 (rx,ry,rz) = rotation 00321 00322 vals = [dx,dy,dz,rx,ry,rz] 00323 (vals2,isAllZeros) = self.writeFloats13E(vals) 00324 if not isAllZeros: 00325 [dx,dy,dz,rx,ry,rz] = vals2 00326 msg.append('%14i %6s %13s %13s %13s %13s %13s %-s\n' %(nodeID,gridType,dx,dy,dz,rx,ry,rz.rstrip())) 00327 ### 00328 ### 00329 msg.append(pageStamp+str(pageNum)+'\n') 00330 if f is not None: 00331 f.write(''.join(msg)) 00332 msg = [''] 00333 pageNum+=1 00334 return (''.join(msg),pageNum-1) 00335 00336 def __reprTransient__(self): 00337 msg = '---TRANSIENT LOAD VECTOR---\n' 00338 #msg += '%s = %g\n' %(self.dataCode['name'],self.dt) 00339 msg += self.writeHeader() 00340 00341 for dt,translations in sorted(self.translations.iteritems()): 00342 msg += '%s = %g\n' %(self.dataCode['name'],dt) 00343 for nodeID,translation in sorted(translations.iteritems()): 00344 rotation = self.rotations[dt][nodeID] 00345 gridType = self.gridTypes[nodeID] 00346 (dx,dy,dz) = translation 00347 (rx,ry,rz) = rotation 00348 00349 msg += '%-10i %8s ' %(nodeID,gridType) 00350 vals = [dx,dy,dz,rx,ry,rz] 00351 for val in vals: 00352 if abs(val)<1e-6: 00353 msg += '%10s ' %(0) 00354 else: 00355 msg += '%10.3e ' %(val) 00356 ### 00357 msg += '\n' 00358 ### 00359 return msg 00360 00361 def __repr__(self): 00362 if self.nonlinearFactor is not None: 00363 return self.__reprTransient__() 00364 00365 msg = '---LOAD VECTOR---\n' 00366 msg += self.writeHeader() 00367 00368 for nodeID,translation in sorted(self.translations.iteritems()): 00369 rotation = self.rotations[nodeID] 00370 gridType = self.gridTypes[nodeID] 00371 00372 (dx,dy,dz) = translation 00373 (rx,ry,rz) = rotation 00374 00375 msg += '%-10i %-8s ' %(nodeID,gridType) 00376 vals = [dx,dy,dz,rx,ry,rz] 00377 for val in vals: 00378 if abs(val)<1e-6: 00379 msg += '%10s ' %(0) 00380 else: 00381 msg += '%10.3e ' %(val) 00382 ### 00383 msg += '\n' 00384 return msg 00385 00386 def __reprTransient__(self): 00387 return self.writeF06Transient(['',''],'PAGE ',1)[0] 00388 00389 class ThermalLoadVectorObject(ThermalVector): # tableCode=2, thermal=1 00390 def __init__(self,dataCode,isSort1,iSubcase,dt=None): 00391 ThermalVector.__init__(self,dataCode,isSort1,iSubcase,dt) 00392 00393 class ThermalVelocityVectorObject(ThermalVector): # tableCode=10, thermal=1 00394 def __init__(self,dataCode,isSort1,iSubcase,dt=None): 00395 ThermalVector.__init__(self,dataCode,isSort1,iSubcase,dt)