pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
oes_nonlinear.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 
00026 from __future__ import division, print_function
00027 import sys
00028 from math import isnan
00029 
00030 from .real.oes_objects import stressObject,strainObject #,array
00031 
00032 
00033 class NonlinearQuadObject(stressObject):
00034     def __init__(self,dataCode,isSort1,iSubcase,dt=None):
00035         stressObject.__init__(self,dataCode,iSubcase)
00036         #self.eType = 'QUAD4FD' # or CTRIA3
00037         
00038         self.code = [self.formatCode,self.sortCode,self.sCode]
00039         self.eType = {}
00040         self.fiberDistance = {}
00041         self.oxx = {}
00042         self.oyy = {}
00043         self.ozz = {}
00044         self.txy = {}
00045 
00046         self.exx = {}
00047         self.eyy = {}
00048         self.ezz = {}
00049         self.exy = {}
00050 
00051         self.es  = {}
00052         self.eps = {}
00053         self.ecs = {}
00054 
00055         self.dt = dt
00056         if isSort1:
00057             if dt is not None:
00058                 self.add = self.addSort1
00059                 self.addNewEid = self.addNewEidSort1
00060             ###
00061         else:
00062             assert dt is not None
00063             self.add = self.addSort2
00064             self.addNewEid = self.addNewEidSort2
00065         ###
00066 
00067     def deleteTransient(self,dt):
00068         del self.fiberDistance[dt]
00069         del self.oxx[dt]
00070         del self.oyy[dt]
00071         del self.ozz[dt]
00072         del self.txy[dt]
00073 
00074         del self.exx[dt]
00075         del self.eyy[dt]
00076         del self.ezz[dt]
00077         del self.exy[dt]
00078 
00079         del self.es[dt]
00080         del self.eps[dt]
00081         del self.ecs[dt]
00082 
00083     def getTransients(self):
00084         k = self.oxx.keys()
00085         k.sort()
00086         return k
00087 
00088     def addNewTransient(self,dt):
00089         self.fiberDistance[dt] = {}
00090         self.oxx[dt] = {}
00091         self.oyy[dt] = {}
00092         self.ozz[dt] = {}
00093         self.txy[dt] = {}
00094 
00095         self.exx[dt] = {}
00096         self.eyy[dt] = {}
00097         self.ezz[dt] = {}
00098         self.exy[dt] = {}
00099 
00100         self.es[dt]  = {}
00101         self.eps[dt] = {}
00102         self.ecs[dt] = {}
00103 
00104     def addNewEidSort1(self,eType,dt,data):
00105         if dt not in self.oxx:
00106             self.addNewTransient(dt)
00107         (eid,fd,sx,sy,sz,txy,es,eps,ecs,ex,ey,ez,exy) = data
00108         self.fiberDistance[dt][eid] = [fd]
00109         if isnan(sz): sz = 0.
00110         if isnan(ez): ez = 0.
00111         self.eType[eid] = eType
00112         self.oxx[dt][eid] = [sx]
00113         self.oyy[dt][eid] = [sy]
00114         self.ozz[dt][eid] = [sz]
00115         self.txy[dt][eid] = [txy]
00116 
00117         self.exx[dt][eid] = [ex]
00118         self.eyy[dt][eid] = [ey]
00119         self.ezz[dt][eid] = [ez]
00120         self.exy[dt][eid] = [exy]
00121 
00122         self.es[dt][eid]  = [es]
00123         self.eps[dt][eid] = [eps]
00124         self.ecs[dt][eid] = [ecs]
00125 
00126     def addSort1(self,dt,data):
00127         (eid,fd,sx,sy,sz,txy,es,eps,ecs,ex,ey,ez,exy) = data
00128         self.fiberDistance[dt][eid].append(fd)
00129         if isnan(sz): sz = 0.
00130         if isnan(ez): ez = 0.
00131         
00132         self.oxx[dt][eid].append(sx)
00133         self.oyy[dt][eid].append(sy)
00134         self.ozz[dt][eid].append(sz)
00135         self.txy[dt][eid].append(txy)
00136 
00137         self.exx[dt][eid].append(ex)
00138         self.eyy[dt][eid].append(ey)
00139         self.ezz[dt][eid].append(ez)
00140         self.exy[dt][eid].append(exy)
00141 
00142         self.es[dt][eid].append(es)
00143         self.eps[dt][eid].append(eps)
00144         self.ecs[dt][eid].append(ecs)
00145 
00146     def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=None):
00147         msgStart = ['      ELEMENT-ID =     129\n'
00148                     '               N O N L I N E A R   S T R E S S E S   I N   Q U A D R I L A T E R A L   E L E M E N T S    ( Q U A D 4 )\n'
00149                     ' \n',
00150                     '    TIME         FIBER                        STRESSES/ TOTAL STRAINS                     EQUIVALENT    EFF. STRAIN     EFF. CREEP\n'
00151                     '               DISTANCE           X              Y             Z               XY           STRESS    PLASTIC/NLELAST     STRAIN\n']
00152 #0 5.000E-05  -5.000000E-01  -4.484895E+01  -1.561594E+02                 -2.008336E-02   1.392609E+02   0.0            0.0
00153         msgE = {}
00154         msgT = {}
00155         for (dt,Oxxs) in sorted(self.oxx.iteritems()):
00156             header[1] = ' %s = %10.4E\n' %(self.dataCode['name'],dt)
00157 
00158             for (eid,oxxs) in sorted(Oxxs.iteritems()):
00159                 msgE[eid] = header+['      ELEMENT-ID = %8i\n' %(eid)]
00160                 if eid not in msgT:
00161                     msgT[eid] = []
00162                 for i,oxx in enumerate(oxxs):
00163                     fd = self.fiberDistance[dt][eid][i]
00164                     oxx = self.oxx[dt][eid][i]
00165                     oyy = self.oyy[dt][eid][i]
00166                     ozz = self.ozz[dt][eid][i]
00167                     txy = self.txy[dt][eid][i]
00168 
00169                     exx = self.exx[dt][eid][i]
00170                     eyy = self.eyy[dt][eid][i]
00171                     ezz = self.ezz[dt][eid][i]
00172                     exy = self.exy[dt][eid][i]
00173 
00174                     es  = self.es[dt][eid][i]
00175                     eps = self.eps[dt][eid][i]
00176                     ecs = self.ecs[dt][eid][i]
00177                     ([oxx,oyy,ozz,txy,exx,eyy,es,eps,ecs,exx,eyy,ezz,exy],isAllZeros) = self.writeFloats13E([oxx,oyy,ozz,txy,exx,eyy,es,eps,ecs,exx,eyy,ezz,exy])
00178                     if i==0:
00179                         msgT[eid].append(       '0 %9.3E %13s  %13s  %13s  %13s  %13s  %13s  %13s  %-s\n' %(dt,fd,oxx,oyy,ozz,txy,es,eps,ecs))
00180                     else:
00181                         msgT[eid].append('     %9s %13s  %13s  %13s  %13s  %13s\n' %('','',exx,eyy,ezz,exy))
00182                     ###
00183                 ###
00184             ###
00185         ###
00186         msg = []
00187         for eid,e in sorted(msgE.iteritems()):
00188             msg += header+e+msgStart+msgT[eid]
00189             msg.append(pageStamp+str(pageNum)+'\n')
00190             pageNum+=1
00191 
00192         return (''.join(msg),pageNum-1)
00193 
00194     def __repr__(self):
00195         return self.writeF06([],'PAGE ',1)[0]
00196 
00197                 
00198 class HyperelasticQuadObject(stressObject):
00199     def __init__(self,dataCode,isSort1,iSubcase,dt=None):
00200         stressObject.__init__(self,dataCode,iSubcase)
00201         self.eType = 'QUAD4FD'
00202         
00203         self.code = [self.formatCode,self.sortCode,self.sCode]
00204         self.Type = {}
00205         self.IDs = {}
00206         self.oxx = {}
00207         self.oyy = {}
00208         self.txy = {}
00209         self.angle = {}
00210         self.majorP = {}
00211         self.minorP = {}
00212 
00213         self.dt = dt
00214         if isSort1:
00215             if dt is not None:
00216                 self.add = self.addSort1
00217                 self.addNewEid = self.addNewEidSort1
00218             ###
00219         else:
00220             assert dt is not None
00221             self.add = self.addSort2
00222             self.addNewEid = self.addNewEidSort2
00223         ###
00224 
00225     def deleteTransient(self,dt):
00226         del self.fiberDistance[dt]
00227         del self.oxx[dt]
00228         del self.oyy[dt]
00229         del self.txy[dt]
00230 
00231         del self.angle[dt]
00232         del self.majorP[dt]
00233         del self.minorP[dt]
00234 
00235     def getTransients(self):
00236         k = self.oxx.keys()
00237         k.sort()
00238         return k
00239 
00240     def addNewTransient(self,dt):
00241         self.oxx[dt] = {}
00242         self.oyy[dt] = {}
00243         self.txy[dt] = {}
00244         self.angle[dt]  = {}
00245         self.majorP[dt] = {}
00246         self.minorP[dt] = {}
00247 
00248     def addNewEidSort1(self,dt,data):
00249         if dt not in self.oxx:
00250             self.addNewTransient(dt)
00251         (eid,Type,oxx,oyy,txy,angle,majorP,minorP) = data
00252         self.Type[eid] = Type
00253         self.oxx[dt] = {eid:[oxx]}
00254         self.oyy[dt] = {eid:[oyy]}
00255         self.txy[dt] = {eid:[txy]}
00256         self.angle[dt]  = {eid:[angle]}
00257         self.majorP[dt] = {eid:[majorP]}
00258         self.minorP[dt] = {eid:[minorP]}
00259 
00260     def addSort1(self,dt,eid,data):
00261         (ID,oxx,oyy,txy,angle,majorP,minorP) = data
00262         self.oxx[dt][eid].append(oxx)
00263         self.oyy[dt][eid].append(oyy)
00264         self.txy[dt][eid].append(txy)
00265         self.angle[dt][eid].append(angle)
00266         self.majorP[dt][eid].append(majorP)
00267         self.minorP[dt][eid].append(minorP)
00268 
00269     def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False):  ## @todo doesnt support CTRIA3NL (calls them CQUAD4s)
00270         msg = ['           S T R E S S E S   I N   H Y P E R E L A S T I C   Q U A D R I L A T E R A L   E L E M E N T S  ( QUAD4FD )\n',
00271                '  ELEMENT     GRID/    POINT       ---------CAUCHY STRESSES--------             PRINCIPAL STRESSES (ZERO SHEAR)\n',
00272                '     ID       GAUSS      ID      NORMAL-X       NORMAL-Y      SHEAR-XY       ANGLE         MAJOR           MINOR\n',]
00273                #0       1     GAUS         1   7.318995E+00   6.367099E-01  -6.551054E+00   -31.4888    1.133173E+01   -3.376026E+00
00274                #                           2   1.097933E+01   4.149028E+00   6.278160E+00    30.7275    1.471111E+01    4.172537E-01
00275         
00276         for dt,Oxxs in sorted(self.oxx.iteritems()):
00277             #header[-1] = '     LOAD STEP = %12.5E' %(dt)
00278             msg += header
00279             for eid,oxxs in sorted(Oxxs.iteritems()):
00280                 gauss = self.Type[eid]
00281                 oxx = self.oxx[dt][eid]
00282                 oyy = self.oyy[dt][eid]
00283                 txy = self.txy[dt][eid]
00284                 angle = self.angle[dt][eid]
00285                 majorP = self.majorP[dt][eid]
00286                 minorP = self.minorP[dt][eid]
00287                 
00288                 for i in xrange(4): # 1,2,3,4
00289                     if i == 0:
00290                         msg.append('0%8i %8s  %8i  %13E.6  %13E.6  %13E.6  %13E.6  %13E.6  %13E.6\n' %(eid,gauss,i+1,oxx[i],oyy[i],txy[i],angle[i],majorP[i],minorP[i]))
00291                     else:
00292                         msg.append(' %8s %8s  %8i  %13E.6  %13E.6  %13E.6  %13E.6  %13E.6  %13E.6\n' %('','',    i+1,oxx[i],oyy[i],txy[i],angle[i],majorP[i],minorP[i]))
00293                     ###
00294                 ###
00295             ###
00296         ###                    
00297         return (''.join(msg),pageNum)    
00298 
00299     def __repr__(self):
00300         return self.writeF06([],'PAGE ',1)[0]
00301 
00302 class NonlinearRodObject(stressObject):
00303     def __init__(self,dataCode,isSort1,iSubcase,dt=None):
00304         stressObject.__init__(self,dataCode,iSubcase)
00305         #self.eType = 'CROD'
00306         self.eTypeMap = {89:'CRODNL',92:'CONRODNL'}
00307         self.code = [self.formatCode,self.sortCode,self.sCode]
00308 
00309         self.eType = {}
00310         self.axialStress = {}
00311         self.equivStress = {}
00312         self.totalStrain = {}
00313         self.effectivePlasticCreepStrain = {}
00314         self.effectiveCreepStrain  = {}
00315         self.linearTorsionalStress = {}
00316 
00317         self.dt = dt
00318         if isSort1:
00319             if dt is not None:
00320                 self.add = self.addSort1
00321                 #self.addNewEid = self.addNewEidSort1
00322             ###
00323         else:
00324             assert dt is not None
00325             self.add = self.addSort2
00326             #self.addNewEid = self.addNewEidSort2
00327         ###
00328     
00329     def deleteTransient(self,dt):
00330         del self.axialStress[dt]
00331         del self.equivStress[dt]
00332         del self.totalStrain[dt]
00333         del self.effectivePlasticCreepStrain[dt]
00334 
00335         del self.effectiveCreepStrain[dt]
00336         del self.linearTorsionalStress[dt]
00337 
00338     def getTransients(self):
00339         k = self.axialStress.keys()
00340         k.sort()
00341         return k
00342 
00343     def addNewTransient(self,dt):
00344         self.axialStress[dt] = {}
00345         self.equivStress[dt] = {}
00346         self.totalStrain[dt] = {}
00347         self.effectivePlasticCreepStrain[dt] = {}
00348         self.effectiveCreepStrain[dt]  = {}
00349         self.linearTorsionalStress[dt] = {}
00350 
00351     def addSort1(self,eType,dt,data):
00352         if dt not in self.axialStress:
00353             self.addNewTransient(dt)
00354         eid = data[0]
00355         self.eType[eid] = eType
00356         self.axialStress[dt][eid] = data[1]
00357         self.equivStress[dt][eid] = data[2]
00358         self.totalStrain[dt][eid] = data[3]
00359         self.effectivePlasticCreepStrain[dt][eid] = data[4]
00360         self.effectiveCreepStrain[dt][eid]  = data[5]
00361         self.linearTorsionalStress[dt][eid] = data[6]
00362         #print data
00363 
00364     def writeF06(self,header,pageStamp,pageNum=1,f=None,isMagPhase=False):  ## @todo doesnt support CONROD/CTUBE (calls them CRODs)
00365         """
00366         ELEMENT-ID =     102
00367                                  N O N L I N E A R   S T R E S S E S   I N   R O D   E L E M E N T S      ( C R O D )
00368           TIME          AXIAL STRESS         EQUIVALENT         TOTAL STRAIN       EFF. STRAIN          EFF. CREEP        LIN. TORSIONAL
00369                                                STRESS                             PLASTIC/NLELAST          STRAIN              STRESS
00370         2.000E-02        1.941367E+01        1.941367E+01        1.941367E-04        0.0                 0.0                 0.0
00371         3.000E-02        1.941367E+01        1.941367E+01        1.941367E-04        0.0                 0.0                 0.0
00372         """
00373         msg = []
00374         msgStart = ['                         N O N L I N E A R   S T R E S S E S   I N   R O D   E L E M E N T S      ( C R O D )\n',
00375                ' \n',
00376                '    TIME          AXIAL STRESS         EQUIVALENT         TOTAL STRAIN       EFF. STRAIN          EFF. CREEP        LIN. TORSIONAL\n',
00377                '                                         STRESS                             PLASTIC/NLELAST          STRAIN              STRESS\n']
00378         msgE = {}
00379         msgT = {}
00380         for dt,axials in sorted(self.axialStress.iteritems()):
00381             for eid,axial in sorted(axials.iteritems()):
00382                 eqs  = self.equivStress[dt][eid]
00383                 ts   = self.totalStrain[dt][eid]
00384                 epcs = self.effectivePlasticCreepStrain[dt][eid]
00385                 ecs  = self.effectiveCreepStrain[dt][eid]
00386                 lts  = self.linearTorsionalStress[dt][eid]
00387                 #print "dt=%s axials=%s eqs=%s ts=%s epcs=%s ecs=%s lts=%s" %(dt,axial,eqs,ts,epcs,ecs,lts)
00388                 msgE[eid] = '      ELEMENT-ID = %8i\n' %(eid)
00389                 if eid not in msgT:
00390                     msgT[eid] = []
00391                 msgT[eid].append('  %9.3E       %13.6E       %13.6E       %13.6E       %13.6E       %13.6E       %13.6E\n'%(dt,axial,eqs,ts,epcs,ecs,lts))
00392             ###
00393         ###
00394         for eid,e in sorted(msgE.iteritems()):
00395             msg += header+[e]+msgStart+msgT[eid]
00396             msg.append(pageStamp+str(pageNum))
00397 
00398         return (''.join(msg),pageNum)
00399 
00400     def __repr__(self):
00401         return self.writeF06([],'PAGE ',1)[0]
00402 
 All Classes Namespaces Files Functions Variables