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 00028 from .oes_objects import stressObject, strainObject 00029 from pyNastran.op2.op2Errors import InvalidCodeError 00030 00031 class BeamStressObject(stressObject): 00032 """ 00033 [1,0,0] 00034 S T R E S S E S I N B E A M E L E M E N T S ( C B E A M ) 00035 STAT DIST/ 00036 ELEMENT-ID GRID LENGTH SXC SXD SXE SXF S-MAX S-MIN M.S.-T M.S.-C 00037 1 1 0.000 -3.125000E+04 -3.125000E+04 -3.125000E+04 -3.125000E+04 -3.125000E+04 -3.125000E+04 00038 2 1.000 -3.125000E+04 -3.125000E+04 -3.125000E+04 -3.125000E+04 -3.125000E+04 -3.125000E+04 00039 00040 """ 00041 def __init__(self,dataCode,isSort1,iSubcase,dt=None): 00042 stressObject.__init__(self,dataCode,iSubcase) 00043 self.eType = 'CBEAM' 00044 00045 self.code = [self.formatCode,self.sortCode,self.sCode] 00046 self.xxb = {} 00047 self.grids = {} 00048 self.smax = {} 00049 self.smin = {} 00050 self.MS_tension = {} 00051 self.MS_compression = {} 00052 00053 #self.MS_axial = {} 00054 #self.MS_torsion = {} 00055 self.sxc = {} 00056 self.sxd = {} 00057 self.sxe = {} 00058 self.sxf = {} 00059 #self.isImaginary = False 00060 00061 self.dt = dt 00062 if isSort1: 00063 if dt is not None: 00064 self.add = self.addSort1 00065 self.addNewEid = self.addNewEidSort1 00066 ### 00067 else: 00068 assert dt is not None 00069 self.add = self.addSort2 00070 self.addNewEid = self.addNewEidSort2 00071 ### 00072 00073 def getLengthTotal(self): 00074 return 444 # 44+10*40 (11 nodes) 00075 00076 def getLength1(self): 00077 return (44,'ifffffffff') 00078 00079 def getLength2(self): 00080 return (40,'ifffffffff') 00081 00082 def deleteTransient(self,dt): 00083 del self.sxc[dt] 00084 del self.sxd[dt] 00085 del self.sxe[dt] 00086 del self.sxf[dt] 00087 del self.smax[dt] 00088 del self.smin[dt] 00089 del self.MS_tension[dt] 00090 del self.MS_compression[dt] 00091 00092 def getTransients(self): 00093 k = self.smax.keys() 00094 k.sort() 00095 return k 00096 00097 def addNewTransient(self,dt): 00098 """ 00099 initializes the transient variables 00100 """ 00101 #print "addNewTransient_beam+1+0" 00102 self.dt = dt 00103 self.sxc[dt] = {} 00104 self.sxd[dt] = {} 00105 self.sxe[dt] = {} 00106 self.sxf[dt] = {} 00107 self.smax[dt] = {} 00108 self.smin[dt] = {} 00109 self.MS_tension[dt] = {} 00110 self.MS_compression[dt] = {} 00111 00112 def addNewEid(self,dt,eid,out): 00113 #print "Beam Stress addNewEid..." 00114 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00115 #print "eid=%s grid=%s" %(eid,grid) 00116 assert eid >= 0 00117 #assert isinstance(eid,int) 00118 #assert isinstance(grid,int) 00119 self.grids[eid] = [grid] 00120 self.xxb[eid] = [sd] 00121 self.sxc[eid] = [sxc] 00122 self.sxd[eid] = [sxd] 00123 self.sxe[eid] = [sxe] 00124 self.sxf[eid] = [sxf] 00125 self.smax[eid] = [smax] 00126 self.smin[eid] = [smin] 00127 self.MS_tension[eid] = [mst] 00128 self.MS_compression[eid] = [msc] 00129 return eid 00130 00131 def addNewEidSort1(self,dt,eid,out): 00132 #print "Beam Transient Stress addNewEid..." 00133 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00134 00135 assert eid >= 0 00136 if dt not in self.sxc: 00137 self.addNewTransient(dt) 00138 self.grids[eid] = [grid] 00139 self.xxb[eid] = [sd] 00140 self.sxc[dt][eid] = [sxc] 00141 self.sxd[dt][eid] = [sxd] 00142 self.sxe[dt][eid] = [sxe] 00143 self.sxf[dt][eid] = [sxf] 00144 self.smax[dt][eid] = [smax] 00145 self.smin[dt][eid] = [smin] 00146 self.MS_tension[dt][eid] = [mst] 00147 self.MS_compression[dt][eid] = [msc] 00148 return eid 00149 00150 def add(self,dt,eid,out): 00151 #print "Beam Stress add..." 00152 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00153 if grid: 00154 self.grids[eid].append(grid) 00155 self.xxb[eid].append(sd) 00156 self.sxc[eid].append(sxc) 00157 self.sxd[eid].append(sxd) 00158 self.sxe[eid].append(sxe) 00159 self.sxf[eid].append(sxf) 00160 self.smax[eid].append(smax) 00161 self.smin[eid].append(smin) 00162 self.MS_tension[eid].append(mst) 00163 self.MS_compression[eid].append(msc) 00164 ### 00165 00166 def addSort1(self,dt,eid,out): 00167 #print "Beam Transient Stress add..." 00168 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00169 if grid: 00170 self.grids[eid].append(grid) 00171 self.xxb[eid].append(sd) 00172 #self.sd[dt][eid].append(sd) 00173 self.sxc[dt][eid].append(sxc) 00174 self.sxd[dt][eid].append(sxd) 00175 self.sxe[dt][eid].append(sxe) 00176 self.sxf[dt][eid].append(sxf) 00177 self.smax[dt][eid].append(smax) 00178 self.smin[dt][eid].append(smin) 00179 self.MS_tension[dt][eid].append(mst) 00180 self.MS_compression[dt][eid].append(msc) 00181 ### 00182 00183 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00184 if self.nonlinearFactor is not None: 00185 return self.writeF06Transient(header,pageStamp,pageNum,f) 00186 00187 msg = header + [' S T R E S S E S I N B E A M E L E M E N T S ( C B E A M )\n', 00188 ' STAT DIST/\n', 00189 ' ELEMENT-ID GRID LENGTH SXC SXD SXE SXF S-MAX S-MIN M.S.-T M.S.-C\n'] 00190 00191 for eid in sorted(self.smax): 00192 msg.append('0 %8i\n' %(eid)) 00193 #print self.xxb[eid] 00194 for i,nid in enumerate(self.grids[eid]): 00195 #print i,nid 00196 xxb = self.xxb[eid][i] 00197 sxc = self.sxc[eid][i] 00198 sxd = self.sxd[eid][i] 00199 sxe = self.sxe[eid][i] 00200 sxf = self.sxf[eid][i] 00201 sMax = self.smax[eid][i] 00202 sMin = self.smin[eid][i] 00203 SMt = self.MS_tension[eid][i] 00204 SMc = self.MS_compression[eid][i] 00205 (vals2,isAllZeros) = self.writeFloats13E([sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc]) 00206 (sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc) = vals2 00207 msg.append('%19s %4.3f %12s %12s %12s %12s %12s %12s %12s %s\n' %(nid,xxb,sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc.strip())) 00208 ### 00209 msg.append(pageStamp+str(pageNum)+'\n') 00210 if f is not None: 00211 f.write(''.join(msg)) 00212 msg = [''] 00213 return (''.join(msg),pageNum) 00214 00215 def writeF06Transient(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00216 words = [' S T R E S S E S I N B E A M E L E M E N T S ( C B E A M )\n', 00217 ' STAT DIST/\n', 00218 ' ELEMENT-ID GRID LENGTH SXC SXD SXE SXF S-MAX S-MIN M.S.-T M.S.-C\n'] 00219 msg = [] 00220 for dt,SMaxs in sorted(self.smax.iteritems()): 00221 header[1] = ' %s = %10.4E\n' %(self.dataCode['name'],dt) 00222 msg += header + words 00223 for eid,Smax in sorted(SMaxs.iteritems()): 00224 msg.append('0 %8i\n' %(eid)) 00225 for i,nid in enumerate(self.grids[eid]): 00226 xxb = self.xxb[eid][i] 00227 #sd = self.sd[eid][i] 00228 sxc = self.sxc[dt][eid][i] 00229 sxd = self.sxd[dt][eid][i] 00230 sxe = self.sxe[dt][eid][i] 00231 sxf = self.sxf[dt][eid][i] 00232 sMax = self.smax[dt][eid][i] 00233 sMin = self.smin[dt][eid][i] 00234 SMt = self.MS_tension[dt][eid][i] 00235 SMc = self.MS_compression[dt][eid][i] 00236 (vals2,isAllZeros) = self.writeFloats13E([sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc]) 00237 (sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc) = vals2 00238 msg.append('%19s %4.3f %12s %12s %12s %12s %12s %12s %12s %s\n' %(nid,xxb,sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc.strip())) 00239 ### 00240 msg.append(pageStamp+str(pageNum)+'\n') 00241 if f is not None: 00242 f.write(''.join(msg)) 00243 msg = [''] 00244 pageNum+=1 00245 return (''.join(msg),pageNum-1) 00246 00247 def __reprTransient__(self): 00248 msg = '---BEAM STRESSES---\n' 00249 msg += '%-6s %6s %6s %7s' %('EID','eType','NID','xxb') 00250 headers = ['sMax','sMin','MS_tension','MS_compression'] 00251 for header in headers: 00252 msg += '%10s ' %(header) 00253 msg += '\n' 00254 00255 for dt,smax in sorted(self.smax.iteritems()): 00256 msg += '%s = %g\n' %(self.dataCode['name'],dt) 00257 for eid in sorted(smax): 00258 for i,nid in enumerate(self.grids[eid]): 00259 xxb = self.xxb[eid][i] 00260 sMax = self.smax[dt][eid][i] 00261 sMin = self.smin[dt][eid][i] 00262 SMt = self.MS_tension[dt][eid][i] 00263 SMc = self.MS_compression[dt][eid][i] 00264 xxb = round(xxb,2) 00265 00266 msg += '%-6i %6s %6i %7.2f ' %(eid,self.eType,nid,xxb) 00267 vals = [sMax,sMin,SMt,SMc] 00268 for val in vals: 00269 if abs(val)<1e-6: 00270 msg += '%10s ' %('0') 00271 else: 00272 msg += '%10g ' %(val) 00273 ### 00274 msg += '\n' 00275 ### 00276 #print msg 00277 #sys.exit('beamT') 00278 return msg 00279 00280 def __repr__(self): 00281 if self.nonlinearFactor is not None: 00282 return self.__reprTransient__() 00283 00284 msg = '---BEAM STRESSES---\n' 00285 msg += '%-6s %6s %6s %6s' %('EID','eType','NID','xxb') 00286 headers = ['sMax','sMin','MS_tension','MS_compression'] 00287 for header in headers: 00288 msg += '%10s ' %(header) 00289 msg += '\n' 00290 #print "self.code = ",self.code 00291 for eid in sorted(self.smax): 00292 #print self.xxb[eid] 00293 for i,nid in enumerate(self.grids[eid]): 00294 #print i,nid 00295 xxb = self.xxb[eid][i] 00296 sMax = self.smax[eid][i] 00297 sMin = self.smin[eid][i] 00298 SMt = self.MS_tension[eid][i] 00299 SMc = self.MS_compression[eid][i] 00300 00301 xxb = round(xxb,2) 00302 msg += '%-6i %6s %6i %4.2f ' %(eid,self.eType,nid,xxb) 00303 00304 vals = [sMax,sMin,SMt,SMc] 00305 for val in vals: 00306 if abs(val)<1e-6: 00307 msg += '%10s ' %('0') 00308 else: 00309 msg += '%10g ' %(val) 00310 ### 00311 msg += '\n' 00312 #print msg 00313 return msg 00314 00315 class BeamStrainObject(strainObject): 00316 def __init__(self,dataCode,isSort1,iSubcase,dt=None): 00317 strainObject.__init__(self,dataCode,iSubcase) 00318 self.eType = 'CBEAM' #{} # 'CBEAM/CONBEAM' 00319 00320 self.code = [self.formatCode,self.sortCode,self.sCode] 00321 00322 self.xxb = {} 00323 self.grids = {} 00324 self.sxc = {} 00325 self.sxd = {} 00326 self.sxe = {} 00327 self.sxf = {} 00328 self.smax = {} 00329 self.smin = {} 00330 self.MS_tension = {} 00331 self.MS_compression = {} 00332 00333 if self.code in [[1,0,10]]: 00334 #self.isImaginary = False 00335 if dt is not None: 00336 self.addNewTransient = self.addNewTransient 00337 self.addNewEid = self.addNewEidTransient 00338 self.add = self.addTransient 00339 else: 00340 self.addNewEid = self.addNewEid 00341 self.add = self.add 00342 ### 00343 else: 00344 raise InvalidCodeError('beamStress - get the format/sort/stressCode=%s' %(self.code)) 00345 ### 00346 if dt is not None: 00347 self.isTransient = True 00348 self.dt = self.nonlinearFactor 00349 self.addNewTransient() 00350 ### 00351 00352 def getLengthTotal(self): 00353 return 444 # 44+10*40 (11 nodes) 00354 00355 def getLength1(self): 00356 return (44,'ifffffffff') 00357 00358 def getLength2(self): 00359 return (40,'ifffffffff') 00360 00361 def deleteTransient(self,dt): 00362 del self.sxc[dt] 00363 del self.sxd[dt] 00364 del self.sxe[dt] 00365 del self.sxf[dt] 00366 del self.smax[dt] 00367 del self.smin[dt] 00368 del self.MS_tension[dt] 00369 del self.MS_compression[dt] 00370 00371 def getTransients(self): 00372 k = self.smax.keys() 00373 k.sort() 00374 return k 00375 00376 def addNewTransient(self,dt): 00377 """ 00378 initializes the transient variables 00379 @note make sure you set self.dt first 00380 """ 00381 #print "addNewTransient_beam+1+0" 00382 self.dt = dt 00383 self.sxc[dt] = {} 00384 self.sxd[dt] = {} 00385 self.sxe[dt] = {} 00386 self.sxf[dt] = {} 00387 self.smax[dt] = {} 00388 self.smin[dt] = {} 00389 self.MS_tension[dt] = {} 00390 self.MS_compression[dt] = {} 00391 00392 def addNewEid(self,dt,eid,out): 00393 #print "Beam Stress addNewEid..." 00394 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00395 #print "eid=%s grid=%s" %(eid,grid) 00396 assert eid >= 0 00397 #assert isinstance(eid,int) 00398 #assert isinstance(grid,int) 00399 self.grids[eid] = [grid] 00400 self.xxb[eid] = [sd] 00401 self.sxc[eid] = [sxc] 00402 self.sxd[eid] = [sxd] 00403 self.sxe[eid] = [sxe] 00404 self.sxf[eid] = [sxf] 00405 self.smax[eid] = [smax] 00406 self.smin[eid] = [smin] 00407 self.MS_tension[eid] = [mst] 00408 self.MS_compression[eid] = [msc] 00409 return eid 00410 00411 def addNewEidSort1(self,dt,eid,out): 00412 #print "Beam Transient Stress addNewEid..." 00413 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00414 00415 assert eid >= 0 00416 if dt not in self.sxc: 00417 self.addNewTransient(dt) 00418 self.grids[eid] = [grid] 00419 self.xxb[eid] = [sd] 00420 self.sxc[dt][eid] = [sxc] 00421 self.sxd[dt][eid] = [sxd] 00422 self.sxe[dt][eid] = [sxe] 00423 self.sxf[dt][eid] = [sxf] 00424 self.smax[dt][eid] = [smax] 00425 self.smin[dt][eid] = [smin] 00426 self.MS_tension[dt][eid] = [mst] 00427 self.MS_compression[dt][eid] = [msc] 00428 return eid 00429 00430 def add(self,dt,eid,out): 00431 #print "Beam Stress add..." 00432 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00433 if grid: 00434 self.grids[eid].append(grid) 00435 self.xxb[eid].append(sd) 00436 self.sxc[eid].append(sxc) 00437 self.sxd[eid].append(sxd) 00438 self.sxe[eid].append(sxe) 00439 self.sxf[eid].append(sxf) 00440 self.smax[eid].append(smax) 00441 self.smin[eid].append(smin) 00442 self.MS_tension[eid].append(mst) 00443 self.MS_compression[eid].append(msc) 00444 ### 00445 00446 def addSort1(self,dt,eid,out): 00447 #print "Beam Transient Stress add..." 00448 (grid,sd,sxc,sxd,sxe,sxf,smax,smin,mst,msc) = out 00449 if grid: 00450 self.grids[eid].append(grid) 00451 self.xxb[eid].append(sd) 00452 self.smax[dt][eid].append(smax) 00453 self.smin[dt][eid].append(smin) 00454 self.MS_tension[dt][eid].append(mst) 00455 self.MS_compression[dt][eid].append(msc) 00456 ### 00457 00458 def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00459 if self.nonlinearFactor is not None: 00460 return self.writeF06Transient(header,pageStamp,pageNum,f) 00461 00462 msg = header + [' S T R A I N S I N B E A M E L E M E N T S ( C B E A M )\n', 00463 ' STAT DIST/\n', 00464 ' ELEMENT-ID GRID LENGTH SXC SXD SXE SXF S-MAX S-MIN M.S.-T M.S.-C\n'] 00465 00466 for eid in sorted(self.smax): 00467 msg.append('0 %8i\n' %(eid)) 00468 #print self.xxb[eid] 00469 for i,nid in enumerate(self.grids[eid]): 00470 #print i,nid 00471 xxb = self.xxb[eid][i] 00472 sxc = self.sxc[eid][i] 00473 sxd = self.sxd[eid][i] 00474 sxe = self.sxe[eid][i] 00475 sxf = self.sxf[eid][i] 00476 sMax = self.smax[eid][i] 00477 sMin = self.smin[eid][i] 00478 SMt = self.MS_tension[eid][i] 00479 SMc = self.MS_compression[eid][i] 00480 (vals2,isAllZeros) = self.writeFloats13E([sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc]) 00481 (sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc) = vals2 00482 msg.append('%19s %4.3f %12s %12s %12s %12s %12s %12s %12s %s\n' %(nid,xxb,sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc.strip())) 00483 ### 00484 msg.append(pageStamp+str(pageNum)+'\n') 00485 if f is not None: 00486 f.write(''.join(msg)) 00487 msg = [''] 00488 return (''.join(msg),pageNum) 00489 00490 def writeF06Transient(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False): 00491 words = [' S T R A I N S I N B E A M E L E M E N T S ( C B E A M )\n', 00492 ' STAT DIST/\n', 00493 ' ELEMENT-ID GRID LENGTH SXC SXD SXE SXF S-MAX S-MIN M.S.-T M.S.-C\n'] 00494 msg = [] 00495 for dt,SMaxs in sorted(self.smax.iteritems()): 00496 header[1] = ' %s = %10.4E\n' %(self.dataCode['name'],dt) 00497 msg += header + words 00498 for eid,Smax in sorted(SMaxs.iteritems()): 00499 msg.append('0 %8i\n' %(eid)) 00500 for i,nid in enumerate(self.grids[eid]): 00501 xxb = self.xxb[eid][i] 00502 sxc = self.sxc[dt][eid][i] 00503 sxd = self.sxd[dt][eid][i] 00504 sxe = self.sxe[dt][eid][i] 00505 sxf = self.sxf[dt][eid][i] 00506 sMax = self.smax[dt][eid][i] 00507 sMin = self.smin[dt][eid][i] 00508 SMt = self.MS_tension[dt][eid][i] 00509 SMc = self.MS_compression[dt][eid][i] 00510 (vals2,isAllZeros) = self.writeFloats13E([sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc]) 00511 (sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc) = vals2 00512 msg.append('%19s %4.3f %12s %12s %12s %12s %12s %12s %12s %s\n' %(nid,xxb,sxc,sxd,sxe,sxf,sMax,sMin,SMt,SMc.strip())) 00513 ### 00514 msg.append(pageStamp+str(pageNum)+'\n') 00515 if f is not None: 00516 f.write(''.join(msg)) 00517 msg = [''] 00518 pageNum+=1 00519 return (''.join(msg),pageNum-1) 00520 00521 def __repr__(self): 00522 if self.nonlinearFactor is not None: 00523 return self.__reprTransient__() 00524 00525 msg = '---BEAM STRAINS---\n' 00526 msg += '%-6s %6s %6s %6s' %('EID','eType','NID','xxb') 00527 headers = ['sMax','sMin','MS_tension','MS_compression'] 00528 for header in headers: 00529 msg += '%10s ' %(header) 00530 msg += '\n' 00531 #print "self.code = ",self.code 00532 for eid in sorted(self.smax): 00533 #print self.xxb[eid] 00534 for i,nid in enumerate(self.grids[eid]): 00535 #print i,nid 00536 xxb = self.xxb[eid][i] 00537 sMax = self.smax[eid][i] 00538 sMin = self.smin[eid][i] 00539 SMt = self.MS_tension[eid][i] 00540 SMc = self.MS_compression[eid][i] 00541 00542 xxb = round(xxb,2) 00543 msg += '%-6i %6s %6i %4.2f ' %(eid,self.eType,nid,xxb) 00544 00545 vals = [sMax,sMin,SMt,SMc] 00546 for val in vals: 00547 if abs(val)<1e-6: 00548 msg += '%10s ' %('0') 00549 else: 00550 msg += '%10.3e ' %(val) 00551 ### 00552 msg += '\n' 00553 #print msg 00554 return msg