pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
op2.py
Go to the documentation of this file.
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 #pylint: disable=C0103,W0201,W0223,R0901,R0902,R0904
00026 
00027 from __future__ import division, print_function
00028 import os
00029 import sys
00030 from numpy import array
00031 from struct import unpack
00032 
00033 from pyNastran.op2.fortranFile import FortranFile
00034 from pyNastran.op2.op2Codes import Op2Codes
00035 from pyNastran.op2.op2Errors import (EndOfFileError, InvalidMarkersError,
00036                                      TapeCodeError)
00037 
00038 from pyNastran.op2.tables.resultTable import ResultTable
00039 from pyNastran.op2.tables.geom.geometryTables import GeometryTables
00040 
00041 from pyNastran.bdf.bdf import BDF
00042 from pyNastran.f06.f06Writer import F06Writer
00043 from pyNastran.f06.matlabWriter import MatlabWriter
00044 
00045 class OP2(BDF,
00046           FortranFile, Op2Codes, GeometryTables, ResultTable, F06Writer,
00047           MatlabWriter):
00048 
00049     def setSubcases(self, iSubcases=None):
00050         """
00051         Allows you to read only the subcases in the list of iSubcases
00052         @param iSubcases
00053           list of [subcase1_ID,subcase2_ID]  (default=None; all subcases)
00054         """
00055         ## stores the set of all subcases that are in the OP2
00056         self.subcases = set()
00057         if iSubcases is None or iSubcases==[]:
00058             ## stores if the user entered [] for iSubcases
00059             self.isAllSubcases = True
00060             self.validSubcases = []
00061         else:
00062             ## should all the subcases be read (default=True)
00063             self.isAllSubcases = False
00064             ## the set of valid subcases -> set([1,2,3])
00065             self.validSubcases = set(iSubcases)
00066         self.log.debug("setSubcases - iSubcases = %s" % (self.validSubcases))
00067 
00068     def isValidSubcase(self):
00069         """
00070         lets the code check whether or not to read a subcase
00071         """
00072         if not self.isAllSubcases:
00073             if self.iSubcase in self.validSubcases:
00074                 return True
00075             return False
00076         return True
00077 
00078     def __init__(self, op2FileName, makeGeom=False, debug=True, log=None):
00079         """
00080         Initializes the Op2 object
00081         @param op2FileName
00082           the file to be parsed
00083         @param makeGeom
00084           reads the BDF tables (default=False)
00085         @param debug
00086           prints data about how the OP2 was parsed (default=False)
00087         @param log
00088           a logging object to write debug messages to (@see import logging)
00089         """
00090         BDF.__init__(self, debug=debug, log=log)
00091         self.setSubcases() # initializes the variables
00092         self.log.debug('op2FileName = %s' % (op2FileName))
00093         bdfExtension = '.bdf'
00094         f06Extension = '.f06'
00095         (fname, extension) = os.path.splitext(op2FileName)
00096         self.tableName = 'temp'
00097         
00098         ## should the BDF tables be parsed
00099         self.makeGeom = makeGeom
00100         
00101         ## the input OP2 filename
00102         self.op2FileName = op2FileName
00103         
00104         ## the expected BDF filename (guessed)
00105         self.bdfFileName = fname+bdfExtension
00106         
00107         ## the expected F06 filename (guessed)
00108         self.f06FileName = fname+f06Extension
00109         #print "bdfFileName = ",self.bdfFileName
00110 
00111         ## developer parameter to write the OP2 is ASCII format
00112         ## to better understand it
00113         self.makeOp2Debug = False
00114         
00115         ## BDF Title
00116         self.Title = ''
00117         ## limit output DTs
00118         self.expectedTimes = {}
00119         #self.expectedTimes = {1:array([0.1,0.12])}
00120         
00121         ## file object containing the skipped cards
00122         self.skippedCardsFile = open('skippedCards.out','a')
00123 
00124         ## the list of supported tables (dont edit this)
00125         self.tablesToRead = [
00126              'GEOM1', 'GEOM2', 'GEOM3', 'GEOM4',  # nodes/geometry/loads/BCs
00127              'GEOM1S','GEOM2S','GEOM3S','GEOM4S', # nodes/geometry/loads/BCs - superelements
00128              'GEOM1OLD','GEOM1N', #???
00129              'EPT', 'MPT',  # properties/materials
00130              'EPTS','MPTS', # properties/materials - superelements
00131              'EDTS',         # ???
00132              'DYNAMIC','DYNAMICS',
00133              'DIT',                           # tables (e.g. TABLED1)
00134              'LAMA','BLAMA',                  # eigenvalues
00135 
00136              'BGPDT','BGPDTS',                # boundary grids???
00137              'EQEXIN','EQEXINS','PVT0','CASECC','EDOM',
00138              'DESTAB',                        # design variables
00139              'OQG1','OQGV1',                  # spc forces
00140              'OQMG1',                         # mpc forces
00141              
00142              'OUGV1',                         # displacements                             
00143              'OGPFB1',                        # grid point forces
00144              'OGS1',                          # grid point stresses
00145              
00146              'OEF1X', 'DOEF1','OEFIT',        # element forces
00147              'OPG1','OPGV1','OPNL1',          # applied forces
00148              'OES1','OES1X','OES1X1','OES1C', # stress
00149              'OSTR1C','OSTR1X',               # strains
00150              'OESNLXR','OESNLXD','OESNL1X','OESNLBR', # nonlinear stress
00151 
00152              'OESCP',                       # cylinder stress???
00153              'OESTRCP',                     # cylinder strain???
00154              'OESRT',                       # rotational stress?
00155 
00156              'ONRGY1', # energy
00157              'ONRGY2', # energy (sort2, unsupported)
00158 
00159              'R1TABRG','HISADD',  # SOL 200
00160 
00161               # unsupported frequency results
00162               'OAGPSD2', 'OAGATO2', 'OAGRMS2', 'OAGNO2', 'OAGCRM2',
00163               'OEFPSD2', 'OEFATO2', 'OEFRMS2', 'OEFNO2', 'OEFCRM2',
00164               'OESPSD2', 'OESATO2', 'OESRMS2', 'OESNO2', 'OESCRM2',
00165               'OPGPSD2', 'OPGATO2', 'OPGRMS2', 'OPGNO2', 'OPGCRM2',
00166               'OQGPSD2', 'OQGATO2', 'OQGRMS2', 'OQGNO2', 'OQGCRM2',
00167               
00168               # supported-ish
00169               'OQMPSD2', 'OQMATO2', 'OQMRMS2', 'OQMNO2', 'OQMCRM2',
00170              'OSTRPSD2','OSTRATO2','OSTRRMS2','OSTRNO2','OSTRCRM2',
00171               'OUGPSD2', 'OUGATO2', 'OUGCRM2', 'OUGNO2', 'OUGRMS2',
00172               'OVGPSD2', 'OVGATO2', 'OVGRMS2', 'OVGNO2', 'OVGCRM2',
00173              
00174              ## @todo what do these do???
00175              'OUPV1',
00176              'VIEWTB','ERRORN',
00177              'OFMPF2M','OSMPF2M','OPMPF2M','OGPMPF2M','OLMPF2M',
00178              'PCOMPTS',
00179              'OMM2',
00180              'EDOM',
00181              'STDISP','SDF','MONITOR','AEMONPT',
00182              'OGPWG', # grid point weight
00183              'OQP1',
00184              'OCRUG','OCRPG',
00185 
00186              # new
00187              'AFRF',             'AGRF',
00188              'PMRF','PERF','PFRF',
00189              'FOL',
00190              ]
00191         
00192         ## a dictionary that maps an integer of the subcaseName to the
00193         ## subcaseID
00194         self.iSubcaseNameMap = {}
00195         
00196         ## list of OP2 tables that were read
00197         ## mainly for debugging
00198         self.tableNames = []
00199         
00200         self.__objectsInit__()
00201 
00202     def __objectsInit__(self):
00203         ## ESE
00204         self.eigenvalues = {}
00205 
00206         ## OUG - displacement
00207         self.displacements = {}           # tCode=1 thermal=0
00208         self.displacementsPSD = {}        # random
00209         self.displacementsATO = {}        # random
00210         self.displacementsRMS = {}        # random
00211         self.displacementsCRM = {}        # random
00212         self.displacementsNO  = {}        # random
00213         self.scaledDisplacements = {}     # tCode=1 thermal=8
00214 
00215         ## OUG - temperatures
00216         self.temperatures  = {}           # tCode=1 thermal=1
00217 
00218         ## OUG - eigenvectors
00219         self.eigenvectors = {}            # tCode=7 thermal=0
00220 
00221         ## OUG - velocity
00222         self.velocities = {}              # tCode=10 thermal=0
00223 
00224         ## OUG - acceleration
00225         self.accelerations = {}           # tCode=11 thermal=0
00226 
00227         # OEF - Forces - tCode=4 thermal=0
00228         self.rodForces = {}
00229         self.barForces = {}
00230         self.bar100Forces = {}
00231         self.beamForces = {}
00232         self.bendForces = {}
00233         self.bushForces = {}
00234         self.coneAxForces = {}
00235         self.damperForces = {}
00236         self.gapForces = {}
00237         self.plateForces = {}
00238         self.plateForces2 = {}
00239         self.shearForces  = {}
00240         self.solidPressureForces = {}
00241         self.springForces = {}
00242         self.viscForces = {}
00243         
00244         self.force_VU = {}
00245         self.force_VU_2D = {}
00246         
00247         #OEF - Fluxes - tCode=4 thermal=1
00248         self.thermalLoad_CONV  = {}
00249         self.thermalLoad_CHBDY = {}
00250         self.thermalLoad_1D    = {}
00251         self.thermalLoad_2D_3D = {}
00252         self.thermalLoad_VU    = {}
00253         self.thermalLoad_VU_3D = {}
00254         self.thermalLoad_VUBeam = {}
00255         #self.temperatureForces = {}    # aCode=1  tCode=4 fCode=1 sortCode=0 thermal=1
00256 
00257         # OES - tCode=5 thermal=0 sCode=0,1 (stress/strain)
00258         ## OES - CELAS1/CELAS2/CELAS3/CELAS4 stress
00259         self.celasStress   = {}
00260         ## OES - CELAS1/CELAS2/CELAS3/CELAS4 strain
00261         self.celasStrain   = {}
00262         
00263         ## OES - CTRIAX6
00264         self.ctriaxStress = {}
00265         self.ctriaxStrain = {}
00266 
00267         ## OES - isotropic CROD/CONROD/CTUBE stress
00268         self.rodStress  = {}
00269         ## OES - isotropic CROD/CONROD/CTUBE strain
00270         self.rodStrain  = {}
00271         ## OES - nonlinear CROD/CONROD/CTUBE stress
00272         self.nonlinearRodStress = {}
00273         ## OES - nonlinear CROD/CONROD/CTUBE strain
00274         self.nonlinearRodStrain = {}
00275         ## OES - isotropic CBAR stress
00276         self.barStress  = {}
00277         ## OES - isotropic CBAR strain
00278         self.barStrain  = {}
00279         ## OES - isotropic CBEAM stress
00280         self.beamStress = {}
00281         ## OES - isotropic CBEAM strain
00282         self.beamStrain = {}
00283 
00284         ## OES - isotropic CTRIA3/CQUAD4 stress
00285         self.plateStress = {}
00286         ## OES - isotropic CTRIA3/CQUAD4 strain
00287         self.plateStrain = {}
00288         ## OESNLXR - CTRIA3/CQUAD4 stress
00289         self.nonlinearPlateStress = {}
00290         ## OESNLXR - CTRIA3/CQUAD4 strain
00291         self.nonlinearPlateStrain = {}
00292         self.hyperelasticPlateStress = {}
00293         self.hyperelasticPlateStrain = {}
00294 
00295         ## OES - isotropic CTETRA/CHEXA/CPENTA stress
00296         self.solidStress = {}
00297         ## OES - isotropic CTETRA/CHEXA/CPENTA strain
00298         self.solidStrain = {}
00299         ## OES - composite CTRIA3/CQUAD4 stress
00300         self.compositePlateStress = {}
00301         ## OES - composite CTRIA3/CQUAD4 strain
00302         self.compositePlateStrain = {}
00303         
00304         ## OES - CSHEAR stress
00305         self.shearStress = {}
00306         ## OES - CSHEAR strain
00307         self.shearStrain = {}
00308         
00309 
00310         # OQG - spc/mpc forces
00311         self.spcForces      = {}  # tCode=3?
00312         self.mpcForces      = {}  # tCode=39
00313         
00314         ## OGF - grid point forces
00315         self.gridPointForces = {} # tCode=19
00316 
00317         ## OGS1 - grid point stresses
00318         self.gridPointStresses = {}       # tCode=26
00319         self.gridPointVolumeStresses = {} # tCode=27
00320 
00321         ## OPG - summation of loads for each element
00322         self.loadVectors  = {}       # tCode=2  thermal=0
00323         self.thermalLoadVectors = {} # tCode=2  thermal=1
00324         self.appliedLoads = {}       # tCode=19 thermal=0
00325         self.forceVectors = {}       # tCode=12 thermal=0
00326         
00327         ## OEE - strain energy density
00328         self.strainEnergy = {} # tCode=18
00329 
00330     def readTapeCode2(self):
00331         data = self.op2.read(28)
00332         (f1, two, f2, f3, tableName, f4) = unpack('4i8si', data)
00333         #print("tableName = ",tableName)
00334         #data = self.op2.read(16)
00335         #print(self.printSection(200))
00336         
00337         sys.exit('')
00338 
00339     def readTapeCode(self):
00340         """
00341         Reads the OP2 header.  This table is still very much in development.
00342         @todo whats in this table?
00343         """
00344         #self.printSection(500)
00345         #sys.exit('op2-readTapeCode')
00346 
00347         if 0:  # param post 0
00348             marker = 0
00349             #print self.printSection(200)
00350             sys.exit('stopping in readTapeCode in op2.py')
00351             while marker != -1:
00352                 ints = self.readIntBlock()
00353                 marker = ints[0]
00354                 #print "ints1 = ",ints
00355             #print ""
00356 
00357             while marker != -2:
00358                 ints = self.readIntBlock()
00359                 marker = ints[0]
00360                 #print "ints2 = ",ints
00361             #print ""
00362             while marker != -3:
00363                 ints = self.readIntBlock()
00364                 marker = ints[0]
00365                 #print "ints3 = ",ints
00366             #print ""
00367             while marker != -4:
00368                 ints = self.readIntBlock()
00369                 marker = ints[0]
00370                 #print "ints4 = ",ints
00371             #print ""
00372             #while marker != -1:
00373                 #ints = self.readIntBlock()
00374                 #marker = ints[0]
00375                 #print "ints1 = ",ints
00376             #print ""
00377             self.readMarkers([2])
00378 
00379             #print self.printSection(200)
00380             ints2 = self.readIntBlock()
00381             ints3 = self.readIntBlock()
00382             #print "ints2 = ",ints2
00383             #print "ints3 = ",ints3
00384             sys.exit('stopping...')
00385 
00386         self.readMarkers([3])
00387         #print(self.printSection(20))
00388         ints = self.readIntBlock()
00389         if self.makeOp2Debug:
00390             self.op2Debug.write('%s\n' %(str(ints)))
00391         #print "*ints = ",ints
00392         self.readMarkers([7])
00393 
00394         word = self.readStringBlock() # Nastran Fort Tape ID Code - 
00395         #print "word = |%r|" %(word)
00396 
00397         self.readMarkers([2])
00398         ints = self.readIntBlock()
00399         #print "*ints = ",ints
00400 
00401         self.readMarkers([-1])
00402 
00403         #data = self.getData(60)
00404         #self.printBlock(data)
00405 
00406     def readOP2(self):
00407         """
00408         reads the op2 file
00409         """
00410         ## the OP2 file object
00411         self.op2 = open(self.op2FileName,'rb')
00412         
00413         if self.makeOp2Debug:
00414             ## a developer debug file (largely unsupported)
00415             self.op2Debug = open('debug.out','wb')
00416         ## the byte position in the OP2
00417         self.n = self.op2.tell()
00418 
00419         try:
00420             self.readTapeCode()
00421         except:
00422             msg  = 'When this happens, the analysis failed or the code bombed...check the F06.\n'
00423             msg += '  If the F06 is OK:\n'
00424             msg += '      1.  Make sure you used PARAM,POST,-1 in your BDF/DAT/NAS\n'
00425             msg += '      2.  Run the problem on a different Operating System\n'
00426             msg += '      3.  Are you running an OP2? :)  \nfname=%s' %(self.op2FileName)
00427             raise TapeCodeError(msg)
00428 
00429         isAnotherTable = True
00430         while isAnotherTable:
00431             self.log.debug('-'*80)
00432             try:
00433                 tableName = self.readTableName(rewind=True, stopOnFailure=False)
00434                 print("tableName = %s" %(tableName))
00435             except EndOfFileError:  # the isAnotherTable method sucks...
00436                 isAnotherTable = False
00437                 self.log.debug("***ok exit, but it could be better...")
00438                 break
00439             except InvalidMarkersError:  # the isAnotherTable method sucks...
00440                 isAnotherTable = False
00441                 self.log.debug("***poor exit, but it worked...")
00442                 #raise
00443                 break
00444             except:
00445                 raise
00446             self.log.debug("tableName = |%r|" % (tableName))
00447             #print("tableName = |%r|" %(tableName))
00448             
00449             if tableName == None:
00450                 break
00451             else:
00452                 isAnotherTable = self.readTable(tableName)
00453             ###
00454 
00455         self.log.debug("---end of all tables---")
00456         self.skippedCardsFile.close()
00457         
00458     def readTable(self, tableName):
00459         if tableName in self.tablesToRead:
00460             self.tableName = tableName
00461             self.isRegular = True
00462             try:
00463                 #print("startTell = %s" %(self.op2.tell()))
00464                 if tableName == 'GEOM1': # nodes,coords,etc.
00465                     self.readTable_Geom1()
00466                 elif tableName == 'GEOM1S': # superelements - nodes,coords,etc.
00467                     self.readTable_Geom1S()
00468                 elif tableName == 'GEOM2S': # superelements - elements
00469                     self.readTable_Geom2S()
00470                 elif tableName == 'GEOM3S': # superelements - static/thermal loads
00471                     self.readTable_Geom3S()
00472                 elif tableName == 'GEOM4S': # superelements - constraints
00473                     self.readTable_Geom4S()
00474 
00475                 #elif tableName=='GEOM1OLD':
00476                 #    self.readTable_Geom1Old()
00477                 #elif tableName=='GEOM1N':
00478                 #    self.readTable_Geom1N()
00479                 elif tableName == 'GEOM2': # elements
00480                     self.readTable_Geom2()
00481                 elif tableName == 'GEOM3': # static/thermal loads
00482                     self.readTable_Geom3()
00483                 elif tableName == 'GEOM4': # constraints
00484                     self.readTable_Geom4()
00485 
00486                 elif tableName in ['EPT', 'EPTS']:  # element properties
00487                     self.readTable_EPT()
00488                 elif tableName in ['MPT', 'MPTS']:  # material properties
00489                     self.readTable_MPTS()
00490                 elif tableName in ['DYNAMIC', 'DYNAMICS']:  # dyanmic info
00491                     self.readTable_DYNAMICS()
00492                 elif  tableName in ['DIT']:  # tables...TABLED1/TABLEM1/TABLES1/GUST
00493                     self.readTable_DIT()
00494                 elif tableName in ['LAMA', 'BLAMA']: # eigenvalue
00495                     self.readTable_LAMA()
00496 
00497                 elif tableName in ['VIEWTB', 'EQEXIN', 'EQEXINS', 'OEFIT',
00498                                    'GEOM1N', 'OGPWG','GEOM1OLD']:
00499                     self.readTable_DUMMY_GEOM(tableName)
00500                 elif tableName in ['OMM2']:
00501                     self.readTable_OMM2()
00502                 elif tableName in ['DESTAB']:  # design variable table
00503                     self.readTable_DesTab()
00504                 elif tableName in ['R1TABRG']: # not done - response table
00505                     self.readTable_R1TAB()
00506                     self.isOptimization = True
00507                 elif tableName in ['HISADD']: # not done
00508                     self.readTable_R1TAB()
00509                     self.isOptimization = True
00510                 elif tableName in ['ERRORN']: # not done
00511                     self.readTable_R1TAB()
00512 
00513                 elif tableName in ['OPG1', 'OPNL1', 'OGS1', 'OPGV1']:
00514                     self.readTable_OPG() # table of applied loads
00515                 elif tableName in ['OGPFB1',]:
00516                     self.readTable_OGF()
00517                 elif tableName in ['OCRUG','OCRPG']:  # totally guessing...
00518                     self.readTable_OUG()
00519 
00520 
00521                 elif tableName in ['OEF1X','DOEF1', 'OEFPSD2', 'OEFATO2',
00522                                    'OEFRMS2','OEFNO2','OEFCRM2',]:
00523                     self.readTable_OEF() # applied loads
00524                 elif tableName in ['OQG1', 'OQGV1', 'OQP1',]:  # spc forces
00525                     self.readTable_OQG()
00526                 elif tableName in ['OQMG1', 'OQMPSD2', 'OQMATO2', 'OQMRMS2',
00527                                    'OQMNO2', 'OQMCRM2',]: # mpc forces
00528                     #self.readTable_OQG()
00529                     self.readTable_DUMMY_GEOM(tableName)
00530  
00531                 elif tableName in ['OUGV1', 'OUPV1']:
00532                     self.readTable_OUG() # displacements/velocity/acceleration
00533                 elif tableName in ['OUGPSD2', 'OUGATO2', 'OUGRMS2', 'OUGNO2',
00534                                    'OUGCRM2']: # OUG tables???
00535                     self.readTable_OUG()
00536 
00537                 elif tableName in ['OES1', 'OES1X', 'OES1X1', 'OSTR1X',
00538                                    'OES1C', 'OESCP', 'OESRT', 'OESNLXR',
00539                                    'OESNL1X']:
00540                     self.readTable_OES()  # stress
00541                 elif tableName in ['OSTR1X','OSTR1C',]:
00542                     self.readTable_OES() # strain
00543                 elif tableName in ['OESTRCP', 'OESNLXD', 'OESNLXR',]:
00544                     self.readTable_OES() # ??? stress/strain
00545                 elif tableName in ['OSTRATO2', 'OSTRPSD2', 'OESRMS2', 'OESNO2',
00546                                    'OESCRM2', 'OSTRRMS2', 'OESRMS2', 'OSTRNO2',
00547                                    'OESCRM2', 'OSTRCRM2',]: # unhandled
00548                     self.readTable_OES()
00549 
00550                 #elif tableName in ['OESNLXD',]: # dont use this, testing only
00551                     #self.readTable_OES() # NLXD
00552                 #elif tableName in ['OESNLXR',]: # dont use this
00553                     #self.readTable_OES()  # NLXR
00554                 
00555                 elif tableName in ['ONRGY1']: # energy
00556                     self.readTable_OEE()
00557                 elif tableName in ['ONRGY2']:
00558                     self.readTable_OEE()
00559 
00560                 elif tableName in ['PCOMPTS']:
00561                     self.readTable_PCOMPTS()
00562                 elif tableName in ['SDF']: # ???
00563                     self.readTable_SDF()
00564                 #elif tableName in ['CASECC']:
00565                     #self.readTable_CASECC()
00566 
00567                 # not done
00568                 elif tableName in []:
00569                     self.readTableB_DUMMY()
00570                 elif tableName in ['MONITOR', 'PMRF', 'PERF', 'PFRF',
00571                                    'AEMONPT', 'FOL', 'AFRF', 'AGRF',]:
00572                     self.readTableB_DUMMY()
00573                 #elif tableName in []:
00574                 #    self.readTableB_DUMMY()
00575 
00576                 elif tableName in ['STDISP', 'FOL', 'OFMPF2M', 'OSMPF2M',
00577                                    'OPMPF2M', 'OGPMPF2M', 'OLMPF2M',
00578                                    'OVGPSD2']:
00579                     self.readTable_DUMMY_GEOM(tableName)
00580                 elif tableName in ['OVGATO2', 'OVGRMS2', 'OVGNO2']:
00581                     self.readTable_DUMMY_GEOM(tableName)
00582 
00583                 elif tableName in ['OESNLXR', 'OESNL1X', 'OESPSD2', 'OESNLBR',
00584                                    'OESATO2',]:
00585                     self.readTable_DUMMY_GEOM(tableName)
00586                 elif tableName in ['OVGCRM2', 'OAGPSD2', 'OAGATO2', 'OAGRMS2',
00587                                    'OAGNO2', 'OAGCRM2', 'OPGPSD2', 'OPGPSD2',
00588                                    'OPGPSD2', 'OPGATO2']:
00589                     self.readTable_DUMMY_GEOM(tableName)
00590                 elif tableName in ['OPGRMS2', 'OPGNO2', 'OPGCRM2', 'OQGPSD2',]:
00591                     self.readTable_DUMMY_GEOM(tableName)
00592                 elif tableName in ['OQGPSD2', 'OQGATO2', 'OQGRMS2', 'OQGNO2',
00593                                    'OQGCRM2', 'PVT0', 'CASECC', 'EDOM',]:
00594                     self.readTable_DUMMY_GEOM(tableName)
00595                 elif tableName in ['BGPDT', 'BGPDTS', 'EDTS',]:
00596                     self.readTable_DUMMY_GEOM(tableName)
00597                 else:
00598                     msg = 'unhandled tableName=|%s|' % (tableName)
00599                     raise KeyError(msg)
00600                 #print("endTell   = ",self.op2.tell())
00601                 #print("---isAnotherTable---")
00602                 (isAnotherTable) = self.hasMoreTables()
00603                 #isAnotherTable = True
00604             except EndOfFileError:
00605                 isAnotherTable = False
00606             ###
00607         else:
00608             if tableName not in [None]:
00609                 assert 1 == 0, '%s is not supported' % (tableName)
00610             (isAnotherTable) = self.skipNextTable()
00611             #return isAnotherTable
00612         #print(self.printSection(140))
00613         self.log.debug("*** finished tableName = |%r|" % (tableName))
00614         ###
00615         return isAnotherTable
00616 
00617     def parseSortCode(self):
00618         """
00619         sortCode = 0 -> sortBits = [0,0,0]
00620         sortCode = 1 -> sortBits = [0,0,1]
00621         sortCode = 2 -> sortBits = [0,1,0]
00622         sortCode = 3 -> sortBits = [0,1,1]
00623         etc.
00624         sortCode = 7 -> sortBits = [1,1,1]
00625 
00626         sortBits[0] = 0 -> isSort1=True  isSort2=False
00627         sortBits[1] = 0 -> isReal=True   isReal/Imaginary=False
00628         sortBits[2] = 0 -> isSorted=True isRandom=False
00629         """
00630         bits = [0, 0, 0]
00631         
00632         sortCode = self.sortCode
00633         i = 2
00634         #print("***sortCode = ",self.sortCode)
00635         while sortCode > 0:
00636             value = sortCode % 2
00637             sortCode = (sortCode - value)//2
00638             bits[i] = value
00639             #print("    *bit = %s" %(value))
00640             #print("    sortCode = %s" %(sortCode))
00641             i -= 1
00642         #print("sortBits = %s" %(bits))
00643         ## the bytes describe the SORT information
00644         self.sortBits = bits
00645         
00646         self.dataCode['sortBits'] = self.sortBits
00647 
00648     def parseApproachCode(self, data):
00649         """
00650         int3 is the 3rd word in table=-3 and may be 
00651         elementType or something else depending on the table type
00652         """
00653         (aCode, tCode, int3, iSubcase) = unpack(b'iiii', data[:16])
00654         ## the local subcase ID
00655         self.iSubcase = iSubcase
00656         #print("iSubcase = %s" %(iSubcase))
00657         self.subcases.add(self.iSubcase) # set notation
00658 
00659         ## the type of result being processed
00660         self.tableCode = tCode % 1000
00661         ## used to create sortBits
00662         self.sortCode = tCode//1000
00663         ## what type of data was saved from the run; used to parse the
00664         ## approachCode and gridDevice.  deviceCode defines what options
00665         ## inside a result, STRESS(PLOT,PRINT), are used.
00666         self.deviceCode = aCode % 10
00667         ## what solution was run (e.g. Static/Transient/Modal)
00668         self.analysisCode = (aCode-self.deviceCode) // 10
00669 
00670         if self.deviceCode == 3:
00671             #sys.stderr.write('The op2 may be inconsistent...\n')
00672             #sys.stderr.write("  print and plot can cause bad results...if there's a crash, try plot only\n")
00673             self.deviceCode = 1
00674             
00675             #self.log.info('The op2 may be inconsistent...')
00676             #self.log.info("  print and plot can cause bad results...if there's a crash, try plot only")
00677             #pass
00678 
00679         ## dataCode stores the active variables; these pass important
00680         ## self variables into the result object
00681         self.dataCode = {'analysisCode': self.analysisCode,
00682                          'deviceCode'  : self.deviceCode,
00683                          'tableCode'   : self.tableCode,
00684                          'sortCode'    : self.sortCode,
00685                          'dt'          : None,
00686                          'log'         : self.log,
00687                          }
00688         #print("iSubcase = ",self.iSubcase)
00689         self.parseSortCode()
00690 
00691         #print("aCode(1)=%s analysisCode=%s deviceCode=%s tCode(2)=%s tableCode=%s sortCode=%s iSubcase(4)=%s" %(aCode,self.analysisCode,self.deviceCode,tCode,self.tableCode,self.sortCode,self.iSubcase))
00692         #self.log.debug(self.printTableCode(self.tableCode))
00693         return (int3)
00694 
00695     def getValues(self, data, iFormat, iWordStart, iWordStop=None):
00696         """
00697         extracts the ith word from the data structure as the provided type
00698         supports multiple inputs with iWordStop (note this is words,
00699                                                  not outputs)
00700         @param self the object pointer
00701         @param data the binary data that is as long as the buffer size
00702         @param iWordStart the word to start reading from
00703         @param iWordStop  the word to stop reading on (largely unused)
00704         @warning
00705             works with nastran syntax, not standard python syntax
00706             this makes it work with what's documented in the DMAP manual
00707         """
00708         if iWordStop == None:
00709             #print("iWordStart=%s data[%s:%s]" %(iWordStart,iWordStart*4,(iWordStart+1)*4))
00710             ds = data[(iWordStart-1)*4:iWordStart*4]
00711             iFormat = bytes(iFormat)
00712             return unpack(iFormat, ds)[0]
00713         #print("type(data) = ",type(data))
00714         ds = data[(iWordStart-1)*4:(iWordStop-1)*4]
00715         return unpack(iFormat, ds)
00716         
00717     def deleteAttributes(self, params):
00718         """
00719         deletes any parameters before going to the next table to avoid
00720         messing up data
00721         """
00722         params += ['dataCode', 'deviceCode', 'analysisCode', 'tableCode',
00723                    'sortCode', 'iSubcase', 'data', 'numWide',
00724                    'nonlinearFactor', 'obj', 'subtitle', 'label']
00725         for param in params:
00726             if hasattr(self, param):
00727                 delattr(self, param)
00728 
00729     def getBufferWords(self):
00730         bufferWords = self.getMarker()
00731         #print("buffMarker = |%s|" %(bufferWords))
00732         #print("bufferWords = ",bufferWords,bufferWords*4)
00733         if bufferWords <=0:
00734             raise BufferError('An invalid buffersize was found...'
00735                           'bufferWords=%s tableName=%s section=\n%s'
00736                         % (bufferWords,self.tableName,self.printSection(200)))
00737         return bufferWords
00738 
00739     def verifyBufferSize(self, bufferWords):
00740         assert bufferWords > 0, self.printSection(220)
00741 
00742     def readTitle(self):
00743         """
00744         reads the Title, Subtitle, and Label.
00745         Puts them in self.iSubcaseNameMap[iSubcase] = [Subtitle,Label]
00746         """
00747         ## the title of the analysis
00748         word = self.readString(384) # titleSubtitleLabel
00749         self.Title    = word[0:128].strip()
00750         ## the subtitle of the subcase
00751         self.subtitle = word[128:256].strip()
00752         ## the label of the subcase
00753         self.label    = word[256:328].strip()
00754 
00755         # not really a hollerith, just the end of the block (so bufferWords*4)
00756         self.readHollerith()
00757 
00758         self.dataCode['subtitle'] = self.subtitle
00759         self.dataCode['label'] = self.label
00760 
00761         if self.iSubcase not in self.iSubcaseNameMap:
00762             self.iSubcaseNameMap[self.iSubcase] = [self.subtitle, self.label]
00763 
00764     def tableInit(self, word):
00765         """
00766         starts a new table
00767         """
00768         ## the local table name
00769         self.tableName = word.strip()
00770         ## the names of all the tables
00771         self.tableNames.append(word)
00772         msg = '*'*20+word+'*'*20+'\n'
00773         #print(msg)
00774 
00775     def getTableNamesFromOP2(self):
00776         """
00777         returns the list of parsed tables
00778         """
00779         return self.tableNames
00780 
00781     def printResults(self):
00782         results = [
00783                    # OUG - Displacements/Velocity/Acceleration/Temperature
00784                    self.displacements, self.displacementsPSD, 
00785                    self.displacementsATO,
00786                    self.temperatures,
00787                    self.eigenvalues,
00788                    self.eigenvectors,
00789                    self.velocities,
00790                    self.accelerations,
00791                    
00792                    # OEF - Applied Forces/Temperatures - ???
00793                    
00794                    # OQG1 - SPC/MPC Forces
00795                    self.spcForces, self.mpcForces,
00796                    
00797                    # OGF - Grid Point Forces
00798                    self.gridPointForces,
00799 
00800                    # OPG - Applied Force/Moment
00801                    self.appliedLoads,
00802                    self.loadVectors, self.thermalLoadVectors,
00803                    self.forceVectors,
00804 
00805                    # OES - Stress/Strain
00806                    self.celasStress, self.celasStrain,
00807                    self.rodStress, self.rodStrain,
00808                    self.nonlinearRodStress, self.nonlinearRodStrain,
00809 
00810                    self.barStress, self.barStrain,
00811                    self.beamStress, self.beamStrain,
00812                    self.plateStress, self.plateStrain,
00813                    self.solidStress, self.solidStrain,
00814                    self.compositePlateStress, self.compositePlateStrain,
00815                    self.ctriaxStress, self.ctriaxStrain,
00816                    
00817                    # OEE - Strain Energy
00818                    self.strainEnergy,
00819                    ]
00820         
00821         msg = '---ALL RESULTS---\n'
00822         for result in results:
00823             for (iSubcase, res) in sorted(result.iteritems()):
00824                 msg += 'iSubcase = %s\n' % (iSubcase)
00825                 try:
00826                     msg += str(res) + '\n'
00827                 except:
00828                     print('failed on %s' % (res.__class__.__name__))
00829                     raise
00830         return msg
00831 
 All Classes Namespaces Files Functions Variables