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 00031 from .realForces import RealForces 00032 from .complexForces import ComplexForces 00033 00034 00035 from .oef_forceObjects import (RealRodForce,RealCBeamForce,RealCShearForce, 00036 RealSpringForce,RealDamperForce,RealViscForce, 00037 RealPlateForce,RealConeAxForce,RealPLATE2Force, 00038 RealCBAR100Force,RealCGAPForce,RealBendForce, 00039 RealPentaPressureForce,RealCBUSHForce, 00040 RealForce_VU_2D,RealCBARForce,RealForce_VU) 00041 from .oef_complexForceObjects import (ComplexRodForce,ComplexCBeamForce, 00042 ComplexCShearForce,ComplexSpringForce, 00043 ComplexDamperForce,ComplexViscForce, 00044 ComplexPlateForce,ComplexPLATE2Force, 00045 ComplexBendForce, 00046 ComplexPentaPressureForce, 00047 ComplexCBUSHForce,ComplexForce_VU_2D, 00048 ComplexCBARForce,ComplexForce_VU) 00049 from .thermal_elements import ThermalElements 00050 00051 class OEF(ThermalElements,RealForces,ComplexForces): 00052 """Table of element forces""" 00053 def readTable_OEF(self): 00054 table3 = self.readTable_OEF_3 00055 table4Data = self.readOEF_Data 00056 self.readResultsTable(table3,table4Data) 00057 self.deleteAttributes_OEF() 00058 00059 def deleteAttributes_OEF(self): 00060 params = ['elementType','dLoadID','loadID','obj','markerStart','oCode', 00061 'eigr','eigi','eign','mode','freq','time','thermal',] 00062 self.deleteAttributes(params) 00063 #print self.obj 00064 00065 def readTable_OEF_3(self,iTable): # iTable=-3 00066 bufferWords = self.getMarker() 00067 #print "2-bufferWords = ",bufferWords,bufferWords*4,'\n' 00068 00069 data = self.getData(4) 00070 bufferSize, = unpack('i',data) 00071 data = self.getData(4*50) 00072 #self.printBlock(data) 00073 00074 aCode = self.getBlockIntEntry(data,1) 00075 00076 self.parseApproachCode(data) 00077 self.addDataParameter(data,'elementType', 'i', 3, False) ## element type 00078 self.addDataParameter(data,'dLoadID', 'i', 8, False) ## dynamic load set ID/random code 00079 self.addDataParameter(data,'formatCode', 'i', 9, False) ## format code 00080 self.addDataParameter(data,'numWide', 'i', 10, False) ## number of words per entry in record; @note is this needed for this table ??? 00081 self.addDataParameter(data,'oCode', 'i', 11, False) ## undefined in DMAP... 00082 self.addDataParameter(data,'thermal', 'i', 23, False) ## thermal flag; 1 for heat ransfer, 0 otherwise 00083 00084 #print "dLoadID(8)=%s formatCode(9)=%s numwde(10)=%s oCode(11)=%s thermal(23)=%s" %(self.dLoadID,self.formatCode,self.numWide,self.oCode,self.thermal) 00085 #print "thermal(23)=%s elementType(3)=%s" %(self.thermal,self.elementType) 00086 00087 #if not self.isSort1(): 00088 #raise NotImplementedError('sort2...') 00089 00090 ## assuming tCode=1 00091 if self.analysisCode==1: # statics 00092 self.addDataParameter(data,'loadID','i',5,False) ## load set ID number 00093 #self.applyDataCodeValue('dataNames',['lsdvmn']) 00094 self.applyDataCodeValue('dataNames',['loadID']) 00095 self.setNullNonlinearFactor() 00096 elif self.analysisCode==2: # normal modes/buckling (real eigenvalues) 00097 self.addDataParameter(data,'mode','i',5) ## mode number 00098 self.addDataParameter(data,'eign','f',6,False) ## eigenvalue 00099 self.applyDataCodeValue('dataNames',['mode','eigr','modeCycle']) 00100 #print "mode(5)=%s eigr(6)=%s modeCycle(7)=%s" %(self.mode,self.eigr,self.modeCycle) 00101 elif self.analysisCode==3: # differential stiffness 0 00102 self.addDataParameter(data,'loadID','i',5) ## load set ID number 00103 self.applyDataCodeValue('dataNames',['loadID']) 00104 elif self.analysisCode==4: # differential stiffness 1 00105 self.addDataParameter(data,'loadID','i',5) ## load set ID number 00106 self.applyDataCodeValue('dataNames',['loadID']) 00107 elif self.analysisCode==5: # frequency 00108 self.addDataParameter(data,'freq','f',5) ## frequency 00109 self.applyDataCodeValue('dataNames',['freq']) 00110 elif self.analysisCode==6: # transient 00111 self.addDataParameter(data,'time','f',5) ## time step 00112 self.applyDataCodeValue('dataNames',['time']) 00113 elif self.analysisCode==7: # pre-buckling 00114 self.addDataParameter(data,'loadID','i',5) ## load set ID number 00115 #self.applyDataCodeValue('dataNames',['lsdvmn']) 00116 self.applyDataCodeValue('dataNames',['loadID']) 00117 elif self.analysisCode==8: # post-buckling 00118 self.addDataParameter(data,'loadID','i',5) ## load set ID number 00119 self.addDataParameter(data,'eigr','f',6,False) ## real eigenvalue 00120 self.applyDataCodeValue('dataNames',['lsdvmn','eigr']) 00121 #print "loadID(5)=%s eigr(6)=%s" %(self.loadID,self.eigr) 00122 elif self.analysisCode==9: # complex eigenvalues 00123 self.addDataParameter(data,'mode','i',5) ## mode number 00124 self.addDataParameter(data,'eigr','f',6,False) ## real eigenvalue 00125 self.addDataParameter(data,'eigi','f',7,False) ## imaginary eigenvalue 00126 self.applyDataCodeValue('dataNames',['mode','eigr','eigi']) 00127 elif self.analysisCode==10: # nonlinear statics 00128 self.addDataParameter(data,'loadStep','f',5) ## load step 00129 self.applyDataCodeValue('dataNames',['loadStep']) 00130 elif self.analysisCode==11: # geometric nonlinear statics 00131 self.addDataParameter(data,'loadID','i',5) ## load set ID number 00132 self.applyDataCodeValue('dataNames',['loadID']) 00133 #print "loadID(5)=%s" %(self.loadID) 00134 else: 00135 raise RuntimeError('invalid analysisCode...analysisCode=%s' %(str(self.analysisCode)+'\n'+self.codeInformation())) 00136 00137 # tCode=2 00138 #if self.analysisCode==2: # sort2 00139 # self.loadID = self.getValues(data,'i',5) ## load set ID number 00140 00141 #print "*iSubcase=%s"%(self.iSubcase) 00142 #print "analysisCode=%s tableCode=%s thermal=%s" %(self.analysisCode,self.tableCode,self.thermal) 00143 #print self.codeInformation() 00144 00145 if not self.isSort1(): 00146 raise NotImplementedError('sort2...') 00147 00148 #self.printBlock(data) 00149 #print '-'*80 00150 self.readTitle() 00151 00152 def OEF_ForceCode(self): 00153 """ 00154 Gets the numwide codes for the element to determine if 00155 the real or complex result should be found. 00156 The format and sort codes do not always give the right answer... 00157 """ 00158 realMapper = { 00159 1: 3, # CROD 00160 2: 1+(10-1)*11, # CBEAM 00161 3: 3, # CTUBE 00162 4: 17, # CSHEAR 00163 10: 3, # CONROD 00164 11: 2, # CELAS1 00165 12: 2, # CELAS2 00166 13: 2, # CELAS3 00167 14: 2, # CELAS4 00168 00169 20: 2, # CDAMP1 00170 21: 2, # CDAMP2 00171 22: 2, # CDAMP3 00172 23: 2, # CDAMP4 00173 24: 3, # CVISC 00174 33: 9, # CQUAD4 00175 34: 9, # CBAR 00176 35: 7, # CCONEAX 00177 38: 9, # CGAP 00178 40: 8, # CBUSH1D ??? 00179 64: 2+(11-2)*5, # CQUAD8 00180 69: 1+(8-1)*2, # CBEND 00181 70: 2+(11-2)*4, # CTRIAR 00182 74: 9, # CTRIA3 00183 75: 2+(11-2)*4, # CTRIA6 00184 00185 00186 #76: 16, # Acoustic Velocity/Pressure CHEXA ??? 00187 76: None, # dummy so it doesnt go into the real results 00188 77: 10, # Acoustic Velocity/Pressure CPENTA 00189 78: 10, # Acoustic Velocity/Pressure CTETRA 00190 00191 82: 2+(11-2)*5, # CQUADR 00192 95: 9, # composite CQUAD4 ??? 00193 96: 9, # composite CQUAD8 ??? 00194 97: 9, # composite CTRIA3 ??? 00195 98: 9, # composite CTRIA6 ??? 00196 100: 8, # BARS 00197 102: 7, # CBUSH 00198 144: 2+(11-2)*5, # bilinear CQUAD4 00199 189: 6+(19-6)*4, # VUQUAD 00200 190: 6+(19-6)*3, # VUTRIA 00201 191: 4+(12-4)*2, # VUBEAM 00202 200: 9, # CWELD 00203 232: 9, # composite CQUADR ??? 00204 233: 9, # composite TRIAR ??? 00205 235: 9, # punch CQUADR...numWide in DMAP is wrong...left out first entry... 00206 236: 8, # punch CTRIAR 00207 } 00208 imagMapper = { 00209 1: 5, # CROD 00210 2: 1+(17-1)*11, # CBEAM 00211 3: 5, # CTUBE 00212 4: 33, # CSHEAR 00213 10: 5, # CONROD 00214 00215 11: 3, # CELAS1 00216 12: 3, # CELAS2 00217 13: 3, # CELAS3 00218 14: 3, # CELAS4 00219 00220 20: 3, # CDAMP1 00221 21: 3, # CDAMP2 00222 22: 3, # CDAMP3 00223 23: 3, # CDAMP4 00224 24: 5, # CVISC 00225 33: 17, # CQUAD4 00226 34: 17, # CBAR 00227 35: 7, # CCONEAX # needed to not crash the code... 00228 38: 9, # CGAP 00229 40: 8, # CBUSH1D ??? 00230 64: 2+(19-2)*5, # CQUAD8 00231 69: 1+(14-1)*2, # CBEND 00232 70: 2+(19-2)*4, # CTRIAR 00233 74: 17, # CTRIA3 00234 75: 2+(19-2)*4, # CTRIA6 00235 00236 76: 16, # Acoustic Velocity/Pressure CHEXA_PR 00237 77: 16, # Acoustic Velocity/Pressure CPENTA_PR 00238 78: 16, # Acoustic Velocity/Pressure CTETRA_PR 00239 00240 82: 2+(19-2)*5, # CQUADR 00241 95: 9, # composite CQUAD4 ??? 00242 96: 9, # composite CQUAD8 ??? 00243 97: 9, # composite CTRIA3 ??? 00244 98: 9, # composite CTRIA6 ??? 00245 100: 14, # BARS 00246 102: 13, # CBUSH 00247 144: 2+(19-2)*5, # bilinear CQUAD4 00248 189: 6+(31-6)*4, # VUQUAD 00249 190: 6+(31-6)*3, # VUTRIA 00250 191: 4+(18-4)*2, # VUBEAM 00251 200: 17, # CWELD 00252 232: 9, # composite CQUADR ??? 00253 233: 9, # composite TRIAR ??? 00254 235: 17, # punch CQUADR...numWide in DMAP is wrong...left out first entry... 00255 236: 16, # punch CTRIAR 00256 } 00257 00258 Real = realMapper[self.elementType] 00259 Imag = imagMapper[self.elementType] 00260 return (Real, Imag) 00261 00262 def readOEF_Data(self): 00263 """ 00264 OEF1X - 00265 DOEF1 - 00266 """ 00267 if self.tableCode==4 and self.tableName in ['OEF1X','DOEF1']: # Forces/Heat Flux 00268 assert self.tableName in ['OEF1X','DOEF1'],'tableName=%s tableCode=%s' %(self.tableName,self.tableCode) 00269 self.readOEF_Data_table4() 00270 #elif self.tableName in ['OEFATO2','OEFCRM2','OEFPSD2','OEFRMS2','OEFNO2',]: 00271 #self.skipOES_Element() # skipping entire table 00272 else: 00273 self.NotImplementedOrSkip() 00274 ### 00275 00276 def readOEF_Data_table4(self): # Forces/Heat Flux 00277 if self.thermal in [0, 8]: 00278 self.readOEF_Forces() 00279 elif self.thermal == 1: 00280 self.readOEF_Thermal() 00281 else: 00282 self.NotImplementedOrSkip('thermal=%s' %(self.thermal)) 00283 00284 #if self.thermal==8: 00285 # self.NotImplementedOrSkip('thermal=%s' %(self.thermal)) 00286 00287 def readOEF_Forces(self): 00288 #print self.codeInformation() 00289 try: 00290 (numWideReal,numWideImag) = self.OEF_ForceCode() 00291 except KeyError: 00292 self.NotImplementedOrSkip() 00293 00294 if self.elementType in [1,3,10]: # CROD,CTUBE,CONROD 00295 resultName = 'rodForces' 00296 if self.numWide == numWideReal: 00297 self.createTransientObject(self.rodForces,RealRodForce) 00298 self.handleResultsBuffer3(self.OEF_Rod,resultName) 00299 elif self.numWide == numWideImag: 00300 self.createTransientObject(self.rodForces,ComplexRodForce) 00301 self.handleResultsBuffer3(self.OEF_Rod_alt,resultName) 00302 else: 00303 self.NotImplementedOrSkip() 00304 00305 elif self.elementType in [2]: # CBEAM 00306 resultName = 'beamForces' 00307 if self.numWide == numWideReal: 00308 self.createTransientObject(self.beamForces,RealCBeamForce) 00309 self.handleResultsBuffer3(self.OEF_Beam,resultName) 00310 elif self.numWide == numWideImag: 00311 self.createTransientObject(self.beamForces,ComplexCBeamForce) 00312 self.handleResultsBuffer3(self.OEF_Beam_alt,resultName) 00313 else: 00314 self.NotImplementedOrSkip() 00315 00316 elif self.elementType in [4]: # CSHEAR 00317 resultName = 'shearForces' 00318 if self.numWide == numWideReal: 00319 self.createTransientObject(self.shearForces,RealCShearForce) 00320 self.handleResultsBuffer3(self.OEF_Shear,resultName) 00321 elif self.numWide == numWideImag: 00322 self.createTransientObject(self.shearForces,ComplexCShearForce) 00323 self.handleResultsBuffer3(self.OEF_Shear_alt,resultName) 00324 else: 00325 self.NotImplementedOrSkip() 00326 00327 elif self.elementType in [11,12,13,14]: # CELAS1,CELAS2,CELAS3,CELAS4 00328 resultName = 'springForces' 00329 if self.numWide == numWideReal: ## @todo is this correct or is DMAP wrong (CELAS1)??? 00330 self.createTransientObject(self.springForces,RealSpringForce) 00331 self.handleResultsBuffer3(self.OEF_Spring,resultName) 00332 elif self.numWide == numWideImag: 00333 self.createTransientObject(self.springForces,ComplexSpringForce) 00334 self.handleResultsBuffer3(self.OEF_Spring_alt,resultName) 00335 else: 00336 self.NotImplementedOrSkip() 00337 00338 elif self.elementType in [20,21,22,23]: # CDAMP1,CDAMP2,CDAMP3,CDAMP4 00339 resultName = 'damperForces' 00340 if self.numWide == numWideReal: 00341 self.createTransientObject(self.damperForces,RealDamperForce) 00342 self.handleResultsBuffer3(self.OEF_Spring,resultName) # same reader as for springs 00343 elif self.numWide == numWideImag: 00344 self.createTransientObject(self.damperForces,ComplexDamperForce) 00345 self.handleResultsBuffer3(self.OEF_Spring_alt,resultName) 00346 else: 00347 self.NotImplementedOrSkip() 00348 00349 elif self.elementType in [24]: # CVISC 00350 resultName = 'viscForces' 00351 if self.numWide == numWideReal: 00352 self.createTransientObject(self.viscForces,RealViscForce) 00353 self.handleResultsBuffer3(self.OEF_CVisc,resultName) 00354 elif self.numWide == numWideImag: 00355 self.createTransientObject(self.viscForces,ComplexViscForce) 00356 self.handleResultsBuffer3(self.OEF_CVisc_alt,resultName) 00357 else: 00358 self.NotImplementedOrSkip() 00359 00360 elif self.elementType in [33,74,235]: # CQUAD4,CTRIA3,CQUADR 00361 resultName = 'plateForces' 00362 if self.numWide == numWideReal: 00363 #print self.codeInformation() 00364 self.createTransientObject(self.plateForces,RealPlateForce) 00365 self.handleResultsBuffer3(self.OEF_Plate,resultName) 00366 elif self.numWide == numWideImag: 00367 self.createTransientObject(self.plateForces,ComplexPlateForce) 00368 self.handleResultsBuffer3(self.OEF_Plate_alt,resultName) 00369 else: 00370 self.NotImplementedOrSkip() 00371 00372 #elif self.elementType in [235]: # CQUADR 00373 #if self.numWide == numWideReal: 00374 #self.OEF_Plate() 00375 #elif self.numWide == numWideImag: 00376 #self.OEF_Plate_alt() 00377 #else: 00378 #raise NotImplementedError(self.codeInformation()) 00379 elif self.elementType in [35]: # CCONEAX 00380 resultName = 'coneAxForces' 00381 if self.numWide == numWideReal: 00382 self.createTransientObject(self.coneAxForces,RealConeAxForce) 00383 self.handleResultsBuffer3(self.OEF_ConeAx,resultName) 00384 else: 00385 self.NotImplementedOrSkip() 00386 elif self.elementType in [64,70,75,82,144]: # CQUAD8,CTRIAR,CTRIA6,CQUADR,CQUAD4-bilinear 00387 resultName = 'plateForces2' 00388 if self.numWide == numWideReal: 00389 self.createTransientObject(self.plateForces2,RealPLATE2Force) 00390 self.handleResultsBuffer3(self.OEF_Plate2,resultName) 00391 elif self.numWide == numWideImag: 00392 self.createTransientObject(self.plateForces2,ComplexPLATE2Force) 00393 self.handleResultsBuffer3(self.OEF_Plate2_alt,resultName) 00394 else: 00395 self.NotImplementedOrSkip() 00396 elif self.elementType in [34]: # CBAR 00397 resultName = 'barForces' 00398 if self.numWide == numWideReal: 00399 self.createTransientObject(self.barForces,RealCBARForce) 00400 self.handleResultsBuffer3(self.OEF_CBar,resultName) 00401 elif self.numWide == numWideImag: 00402 self.createTransientObject(self.barForces,ComplexCBARForce) 00403 self.handleResultsBuffer3(self.OEF_CBar_alt,resultName) 00404 else: 00405 self.NotImplementedOrSkip() 00406 elif self.elementType in [100]: # CBAR 00407 resultName = 'barForces' 00408 if self.numWide == numWideReal: 00409 self.createTransientObject(self.bar100Forces,RealCBAR100Force) 00410 self.handleResultsBuffer3(self.OEF_CBar100,resultName) 00411 elif self.numWide == numWideImag: 00412 self.handleResultsBuffer3(self.OEF_CBar100_alt,resultName) 00413 else: 00414 self.NotImplementedOrSkip() 00415 elif self.elementType in [38]: # CGAP 00416 resultName = 'gapForces' 00417 if self.numWide == numWideReal: 00418 self.createTransientObject(self.gapForces,RealCGAPForce) 00419 self.handleResultsBuffer3(self.OEF_CGap,resultName) 00420 elif self.numWide == numWideImag: 00421 self.handleResultsBuffer3(self.OEF_CGap_alt,resultName) 00422 else: 00423 self.NotImplementedOrSkip() 00424 elif self.elementType in [69]: # CBEND 00425 resultName = 'bendForces' 00426 if self.numWide == numWideReal: 00427 self.createTransientObject(self.bendForces,RealBendForce) 00428 self.handleResultsBuffer3(self.OEF_Bend,resultName) 00429 elif self.numWide == numWideImag: 00430 self.createTransientObject(self.bendForces,ComplexBendForce) 00431 self.handleResultsBuffer3(self.OEF_Bend_alt,resultName) 00432 else: 00433 self.NotImplementedOrSkip() 00434 elif self.elementType in [76,77,78]: # CHEXA_PR,PENTA_PR,CTETRA_PR 00435 resultName = 'solidPressureForces' 00436 if self.numWide == numWideReal: 00437 self.createTransientObject(self.solidPressureForces,RealPentaPressureForce) 00438 self.handleResultsBuffer3(self.OEF_PentaPressure,resultName) 00439 elif self.numWide == numWideImag: 00440 self.createTransientObject(self.solidPressureForces,ComplexPentaPressureForce) 00441 self.handleResultsBuffer3(self.OEF_PentaPressure_alt,resultName) 00442 else: 00443 self.NotImplementedOrSkip() 00444 #elif self.elementType in [95,96,97,98]: # composite CQUAD4,CQUAD8,CTRIA3,CTRIA6 00445 # resultName = '???' ## @todo why is there no object... 00446 # if self.numWide == numWideReal: 00447 # self.handleResultsBuffer3(self.OEF_CompositePlate,resultName) 00448 # elif self.numWide == numWideImag: 00449 # self.handleResultsBuffer3(self.OEF_CompositePlate_alt) 00450 # else: 00451 # self.NotImplementedOrSkip() 00452 elif self.elementType in [102]: # CBUSH 00453 resultName = 'bushForces' 00454 if self.numWide == numWideReal: 00455 self.createTransientObject(self.bushForces,RealCBUSHForce) 00456 self.handleResultsBuffer3(self.OEF_CBush,resultName) 00457 elif self.numWide == numWideImag: 00458 self.createTransientObject(self.bushForces,ComplexCBUSHForce) 00459 self.handleResultsBuffer3(self.OEF_CBush_alt,resultName) 00460 else: 00461 self.NotImplementedOrSkip() 00462 elif self.elementType in [189,190]: # VUQUAD,VUTRIA 00463 resultName = 'force_VU_2D' 00464 if self.numWide == numWideReal: 00465 self.createTransientObject(self.force_VU_2D,RealForce_VU_2D) 00466 self.handleResultsBuffer3(self.OEF_Force_VUTRIA,resultName) 00467 elif self.numWide == numWideImag: 00468 self.createTransientObject(self.force_VU_2D,ComplexForce_VU_2D) 00469 self.handleResultsBuffer3(self.OEF_Force_VUTRIA_alt,resultName) 00470 else: 00471 self.NotImplementedOrSkip() 00472 elif self.elementType in [191]: # VUBEAM 00473 resultName = 'force_VU' 00474 if self.numWide == numWideReal: 00475 self.createTransientObject(self.force_VU,RealForce_VU) 00476 self.handleResultsBuffer3(self.OEF_Force_VU,resultName) 00477 elif self.numWide == numWideImag: 00478 self.createTransientObject(self.force_VU,ComplexForce_VU) 00479 self.handleResultsBuffer3(self.OEF_Force_VU_alt,resultName) 00480 else: 00481 self.NotImplementedOrSkip() 00482 else: 00483 self.NotImplementedOrSkip() 00484 ###