pyNastran  0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
materials.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,R0902,R0904,R0914,E1101,W0612,E0602
00026 
00027 from __future__ import division, print_function
00028 from numpy import zeros, array
00029 
00030 from pyNastran.bdf.fieldWriter import set_blank_if_default
00031 from pyNastran.bdf.cards.baseCard import BaseCard, Material
00032 from pyNastran.bdf.cards.tables import Table
00033 
00034 class IsotropicMaterial(Material):
00035     """Isotropic Material Class"""
00036     def __init__(self, card, data):
00037         Material.__init__(self, card, data)
00038 
00039 class AnisotropicMaterial(Material):
00040     """Anisotropic Material Class"""
00041     def __init__(self, card, data):
00042         Material.__init__(self, card, data)
00043 
00044 class ThermalMaterial(Material):
00045     """Thermal Material Class"""
00046     def __init__(self, card, data):
00047         Material.__init__(self, card, data) 
00048 
00049 class HyperelasticMaterial(Material):
00050     """Hyperelastic Material Class"""
00051     def __init__(self, card, data):
00052         Material.__init__(self, card, data) 
00053 
00054 class CREEP(Material):
00055     type = 'CREEP'
00056     def __init__(self, card=None, data=None):
00057         Material.__init__(self, card, data)
00058         if card:
00059             self.mid    = card.field(1)
00060             self.T0     = card.field(2, 0.0)
00061             self.exp    = card.field(3, 1e-9)
00062             self.form   = card.field(4)
00063             self.tidkp  = card.field(5)
00064             self.tidcp  = card.field(6)
00065             self.tidcs  = card.field(7)
00066             self.thresh = card.field(8, 1e-5)
00067             self.Type = card.field(9)
00068             self.a = card.field(10)
00069             self.b = card.field(11)
00070             self.c = card.field(12)
00071             self.d = card.field(13)
00072             self.e = card.field(14)
00073             self.f = card.field(15)
00074             self.g = card.field(16)
00075         else:
00076             self.mid    = data[0]
00077             self.T0     = data[1]
00078             self.exp    = data[2]
00079             self.form   = data[3]
00080             self.tidkp  = data[4]
00081             self.tidcp  = data[5]
00082             self.tidcs  = data[6]
00083             self.thresh = data[7]
00084             self.Type   = data[8]
00085             self.a = data[9]
00086             self.b = data[10]
00087             self.c = data[11]
00088             self.d = data[12]
00089             self.e = data[13]
00090             self.f = data[14]
00091             self.g = data[15]
00092         ###
00093     
00094     def crossReference(self, model):
00095         self.mid = model.Material(self.mid)
00096 
00097     def Mid(self): # links up to MAT1, MAT2, MAT9 or same mid
00098         if isinstance(self.mid, int):
00099             return self.mid
00100         return self.mid.mid
00101 
00102     def rawFields(self):
00103         fields = ['CREEP', self.Mid(), self.T0, self.exp, self.form, self.tidkp, self.tidcp, self.tidcs, self.thresh,
00104         self.Type, self.a, self.b, self.c, self.d, self.e, self.f, self.g]
00105         return fields
00106 
00107     def reprFields(self):
00108         thresh = set_blank_if_default(self.thresh, 1e-5)
00109         exp    = set_blank_if_default(self.exp, 4.1e-9)
00110         T0     = set_blank_if_default(self.T0, 0.0)
00111         fields = ['CREEP', self.Mid(), T0, exp, self.form, self.tidkp, self.tidcp, self.tidcs, thresh,
00112         self.Type, self.a, self.b, self.c, self.d, self.e, self.f, self.g]
00113         return fields
00114 
00115 class MAT1(Material):
00116     """
00117     Defines the material properties for linear isotropic materials.
00118     MAT1     1      1.03+7  3.9615+6.3      .098
00119     """
00120     type = 'MAT1'
00121     def __init__(self, card=None, data=None):
00122         Material.__init__(self, card, data)
00123 
00124         if card:
00125             self.mid  = card.field(1)
00126             self.set_E_G_nu(card)
00127             self.rho  = card.field(5, 0.)
00128             self.a    = card.field(6, 0.0)
00129             self.TRef = card.field(7, 0.0)
00130             self.ge   = card.field(8, 0.0)
00131             self.St   = card.field(9, 0.0)
00132             self.Sc   = card.field(10, 0.0)
00133             self.Ss   = card.field(11, 0.0)
00134             self.Mcsid = card.field(12, 0)
00135         else:
00136             self.mid   = data[0]
00137             self.e     = data[1]
00138             self.g     = data[2]
00139             self.nu    = data[3]
00140             self.rho   = data[4]
00141             self.a     = data[5]
00142             self.TRef  = data[6]
00143             self.ge    = data[7]
00144             self.St    = data[8]
00145             self.Sc    = data[9]
00146             self.Ss    = data[10]
00147             self.Mcsid = data[11]
00148 
00149     def D(self):
00150         E11  = self.E()
00151         E22  = E11
00152         nu12 = self.Nu()
00153         G12  = self.G()
00154 
00155         D = zeros((3, 3))
00156         #D = zeros((6,6))
00157         mu = 1.-nu12*nu12 #*E11/E22    # not necessary b/c they're equal
00158         D[0, 0] = E11/mu
00159         D[1, 1] = E22/mu
00160         D[0, 1] = nu12*D[0, 0]
00161         D[1, 0] = D[0, 1]
00162         D[2, 2] = G12
00163         return D
00164 
00165     def G(self):
00166         return self.g
00167     
00168     def E(self):
00169         return self.e
00170     
00171     def Nu(self):
00172         return self.nu
00173 
00174     def set_E_G_nu(self, card):
00175         """
00176         \f[ \large G = \frac{E}{2 (1+\nu)} \f]
00177         """
00178         #self.E  = card.field(2)
00179         #self.G  = card.field(3)
00180         #self.nu = card.field(4)
00181         #return
00182 
00183         E  = card.field(2)
00184         G  = card.field(3)
00185         nu = card.field(4)
00186 
00187         if G is None and E is None: # no E,G
00188             raise RuntimeError('G=%s E=%s cannot both be None' %(G, E))
00189         elif E is not None and G is not None and nu is not None:
00190             pass
00191         elif E is not None and nu is not None:
00192             G = E/2./(1+nu)
00193         elif G is not None and nu is not None:
00194             E = 2*(1+nu)*G
00195         elif G is not None and E is not None:
00196             nu = E/(2*G)-1.
00197         elif G is None and nu is None:
00198             G  = 0.0
00199             nu = 0.0
00200         elif E is None and nu is None:
00201             E  = 0.0
00202             nu = 0.0
00203         else:
00204             msg = 'G=%s E=%s nu=%s' % (G, E, nu)
00205             raise RuntimeError(msg)
00206         self.e = E
00207         self.g = G
00208         self.nu = nu
00209         #print "mid = ",self.mid
00210         #print "E  = ",E
00211         #print "G  = ",G
00212         #print "nu = ",nu
00213         #print ""
00214 
00215     def writeCalculix(self, elementSet='ELSetDummyMat'):
00216         temperature = self.TRef # default value - same properties for all values
00217         msg  = '*ELASTIC,TYPE=ISO,ELSET=%s\n' % (elementSet)
00218         msg += '** E,NU,TEMPERATURE\n'
00219         msg += '%s,%s,%s\n' % (self.e, self.nu, temperature)
00220         
00221         if self.rho > 0.:
00222             msg += '*DENSITY\n'
00223             msg += '%s\n' % (self.rho)
00224         if self.a > 0:
00225             msg += '*EXPANSION,TYPE=ISO,ZERO=%s\n' % (self.TRef)
00226             msg += '** ALPHA,ALPHA*TREF\n'
00227             msg += '%s,%s\n\n' % (self.a, self.a*self.TRef)
00228         return msg
00229 
00230     def writeCodeAster(self):
00231         msg  = 'M%s = DEFI_MATRIAU(ELAS=_F(E=%g, # MAT1 mid=%s\n' % (self.mid, self.e, self.mid)
00232         #msg  = 'M%s = DEFI_MATRIAU(ELAS=_F( # MAT1\n' %(self.mid)
00233         #msg += '                       E  =%g,\n'  %(self.e)
00234         msg += '                       NU =%g,\n'    % (self.nu)
00235         msg += '                       RHO=%g),);\n' % (self.rho)
00236         return msg
00237 
00238     #def crossReference(self, model):
00239         #self.Mcsid = model.Coord(self.Mcsid)  # used only for PARAM,CURVPLOT
00240         #pass
00241 
00242     def rawFields(self):
00243         fields = ['MAT1', self.mid, self.e, self.g, self.nu, self.rho, self.a, self.TRef, self.ge,
00244                   self.St, self.Sc, self.Ss, self.Mcsid]
00245         return fields
00246 
00247     def getG_default(self):
00248         if self.g == 0.0 or self.nu == 0.0:
00249             G = self.g
00250         else:
00251             #G_default = self.e/2./(1+self.nu)
00252             G = self.e/2./(1+self.nu)
00253         #print "MAT1 - self.e=%s self.nu=%s self.g=%s Gdef=%s G=%s" %(self.e, self.nu,self.g, G_default, G)
00254         return G
00255 
00256     def reprFields(self):
00257         G = self.getG_default()
00258 
00259         rho  = set_blank_if_default(self.rho, 0.)
00260         a    = set_blank_if_default(self.a, 0.)
00261         TRef = set_blank_if_default(self.TRef, 0.0)
00262         ge   = set_blank_if_default(self.ge, 0.)
00263         St   = set_blank_if_default(self.St, 0.)
00264         Sc   = set_blank_if_default(self.Sc, 0.)
00265         Ss   = set_blank_if_default(self.Ss, 0.)
00266         Mcsid = set_blank_if_default(self.Mcsid, 0)
00267 
00268         fields = ['MAT1', self.mid, self.e, G, self.nu, rho, a, TRef, ge,
00269                   St, Sc, Ss, Mcsid]
00270         return fields
00271 
00272 class MAT2(AnisotropicMaterial):
00273     """
00274     Defines the material properties for linear anisotropic materials for
00275     two-dimensional elements.
00276 
00277     MAT2 MID G11 G12 G13 G22 G23 G33 RHO
00278     A1 A2 A3 TREF GE ST SC SS
00279     MCSID
00280     """
00281     type = 'MAT2'
00282     def __init__(self, card=None, data=None):
00283         AnisotropicMaterial.__init__(self, card, data)
00284         
00285         if card:
00286             self.mid  = card.field(1)
00287             self.G11  = card.field(2, 0.0)
00288             self.G12  = card.field(3, 0.0)
00289             self.G13  = card.field(4, 0.0)
00290             self.G22  = card.field(5, 0.0)
00291             self.G23  = card.field(6, 0.0)
00292             self.G33  = card.field(7, 0.0)
00293 
00294             self.rho  = card.field(8, 0.)
00295             self.a1   = card.field(9)
00296             self.a2   = card.field(10)
00297             self.a3   = card.field(11)
00298             self.TRef = card.field(12, 0.0)
00299             self.ge   = card.field(13, 0.0)
00300             self.St   = card.field(14)
00301             self.Sc   = card.field(15)
00302             self.Ss   = card.field(16)
00303             self.Mcsid = card.field(17)
00304         else:
00305             self.mid  = data[0]
00306             self.G11  = data[1]
00307             self.G12  = data[2]
00308             self.G13  = data[3]
00309             self.G22  = data[4]
00310             self.G23  = data[5]
00311             self.G33  = data[6]
00312 
00313             self.rho  = data[7]
00314             self.a1   = data[8]
00315             self.a2   = data[9]
00316             self.a3   = data[10]
00317             self.TRef = data[11]
00318             self.ge   = data[12]
00319             self.St   = data[13]
00320             self.Sc   = data[14]
00321             self.Ss   = data[15]
00322             self.Mcsid = data[16]
00323         ###
00324 
00325     def Dsolid(self):
00326         """
00327         Eq 9.4.7 in Finite Element Method using Matlab
00328         """
00329         D = zeros((6, 6))
00330         E    = self.E()
00331         nu12 = self.nu12
00332         nu   = nu12
00333         
00334         mu = 1.-nu12*nu12 #*E11/E22    # not necessary b/c they're equal
00335         Emu = E/mu
00336         D[0, 0] = Emu # E/(1-nu^2)
00337         D[1, 1] = Emu
00338         D[2, 2] = Emu
00339         D[0, 1] = nu*Emu # nu*E/(1-nu^2)
00340         D[1, 2] = D[2, 1] = D[0, 2] = D[2, 0] = D[1, 0] = D[0, 1] # nu*E/(1-nu^2)
00341         D[3, 3] = (1.-nu)*0.5*Emu   # (1.-nu)/2.*E/(1-nu^2)
00342         D[5, 5] = D[4, 4] = D[3, 3] # (1.-nu)/2.*E/(1-nu^2)
00343 
00344     def Dplate(self):
00345         """
00346         Eq 9.1.6 in Finite Element Method using Matlab
00347         """
00348         E    = self.E()
00349         nu12 = self.Nu()
00350         nu   = nu12
00351         G12  = self.G()
00352 
00353         D = zeros((3, 3))
00354         mu = 1.-nu12*nu12 #*E11/E22    # not necessary b/c they're equal
00355         Emu = E/mu
00356         D[0, 0] = Emu
00357         D[1, 1] = Emu
00358         D[0, 1] = nu*Emu
00359         D[1, 0] = D[0, 1]
00360         D[2, 2] = 1.-nu/2.*Emu
00361         #D[4,4] =      ## @ todo verify
00362         #D[5,5] = G22
00363         #D[6,6] = G33
00364         return D
00365 
00366     def writeCalculix(self):
00367         raise NotImplementedError(self.type)
00368         msg  = '*ELASTIC,TYPE=ORTHO\n'
00369         temperature = 0. # default value - same properties for all values
00370         msg += '%s,%s,%s\n' % (self.e, self.nu, temperature)
00371         D = Dplate
00372         D1111 = D[0, 0]
00373         D1122 = 0.
00374         D2222 = D[1, 1]
00375         D1133 = D[0, 2]
00376         D2233 = D[1, 2]
00377         D3333 = D[2, 2]
00378         D1212 = D[0, 1]
00379         D1313 = D[0, 2]
00380         msg += '%s,%s,%s,%s,%s,%s,%s,%s\n\n' % (D1111, D1122, D2222, D1133, D2233, D3333, D1212, D1313)
00381         
00382         G23
00383         temperature = self.TRef
00384         msg = '*ELASTIC,TYPE=ENGINEERING CONSTANTS  ** MAT2,mid=%s\n' % (self.mid)
00385         msg += '** E1,E2,E3,NU12,NU13,NU23,G12,G13\n'
00386         msg += '** G23,TEMPERATURE\n'
00387         msg += '%s,%s,%s,%s,%s,%s,%s,%s\n' % (e1, e2, e3, nu12, nu13, nu23, g12, g13)
00388         msg += '%s,%s\n' % (G23, temperature)
00389         if self.rho > 0.:
00390             msg += '*DENSITY\n'
00391             msg += '%s\n' % (self.rho)
00392         if self.a > 0:
00393             msg += '*EXPANSION,TYPE=ISO,ZERO=%s\n' % (self.TRef)
00394             msg += '** ALPHA,ALPHA*TREF\n'
00395             msg += '%s,%s\n\n' % (self.a, self.a*self.TRef)
00396         return msg
00397 
00398     def rawFields(self):
00399         fields = ['MAT2', self.mid, self.G11, self.G12, self.G13, self.G22, self.G23, self.G33, self.rho,
00400                   self.a1, self.a2, self.a3, self.TRef, self.ge, self.St, self.Sc, self.Ss,
00401                   self.Mcsid]
00402         return fields
00403 
00404     def reprFields(self):
00405         G11 = set_blank_if_default(self.G11, 0.0)
00406         G12 = set_blank_if_default(self.G12, 0.0)
00407         G13 = set_blank_if_default(self.G13, 0.0)
00408         G22 = set_blank_if_default(self.G22, 0.0)
00409         G23 = set_blank_if_default(self.G23, 0.0)
00410         G33 = set_blank_if_default(self.G33, 0.0)
00411         rho = set_blank_if_default(self.rho, 0.0)
00412         TRef = set_blank_if_default(self.TRef, 0.0)
00413         ge   = set_blank_if_default(self.ge, 0.0)
00414         fields = ['MAT2', self.mid, G11, G12, G13, G22, G23, G33, rho,
00415                   self.a1, self.a2, self.a3, TRef, ge, self.St, self.Sc, self.Ss,
00416                   self.Mcsid]
00417         return fields
00418 
00419 class MAT3(AnisotropicMaterial):
00420     """
00421     Defines the material properties for linear orthotropic materials used by the
00422     CTRIAX6 element entry.
00423     MAT3 MID EX  ETH EZ  NUXTH NUTHZ NUZX RHO
00424     -    -   GZX AX  ATH AZ TREF GE
00425     """
00426     type = 'MAT3'
00427     def __init__(self, card=None, data=None):
00428         AnisotropicMaterial.__init__(self, card, data)
00429         if card:
00430             self.mid   = card.field(1)
00431             self.ex    = card.field(2)
00432             self.eth   = card.field(3)
00433             self.ez    = card.field(4)
00434             self.nuxth = card.field(5)
00435             self.nuthz = card.field(6)
00436             self.nuzx  = card.field(7)
00437             self.rho   = card.field(8, 0.)
00438 
00439             self.gzx  = card.field(11)
00440             self.ax   = card.field(12)
00441             self.ath  = card.field(13)
00442             self.az   = card.field(14)
00443             self.TRef = card.field(15, 0.0)
00444             self.ge   = card.field(16, 0.0)
00445         else:
00446             self.mid   = data[0]
00447             self.ex    = data[1]
00448             self.eth   = data[2]
00449             self.ez    = data[3]
00450             self.nuxth = data[4]
00451             self.nuthz = data[5]
00452             self.nuzx  = data[6]
00453 
00454             self.rho  = data[7]
00455             self.gzx  = data[8]
00456             self.ax   = data[9]
00457             self.ath  = data[10]
00458             self.az   = data[11]
00459             self.TRef = data[12]
00460             self.ge   = data[13]
00461 
00462     def rawFields(self):
00463         fields = ['MAT3', self.mid, self.ex, self.eth, self.ez, self.nuxth, self.nuthz, self.nuzx, self.rho,
00464                          None, None, self.gzx, self.ax, self.ath, self.az, self.TRef, self.ge]
00465         return fields
00466 
00467     def reprFields(self):
00468         rho = set_blank_if_default(self.rho, 0.0)
00469         TRef = set_blank_if_default(self.TRef, 0.0)
00470         ge = set_blank_if_default(self.ge, 0.0)
00471         fields = ['MAT3', self.mid, self.ex, self.eth, self.ez, self.nuxth, self.nuthz, self.nuzx, rho,
00472                          None, None, self.gzx, self.ax, self.ath, self.az, TRef, ge]
00473         return fields
00474 
00475 class MAT4(ThermalMaterial):
00476     """
00477     Defines the constant or temperature-dependent thermal material properties
00478     for conductivity, heat capacity, density, dynamic viscosity, heat
00479     generation, reference enthalpy, and latent heat associated with a
00480     single-phase change.
00481 
00482     MAT4 MID K CP H HGEN REFENTH
00483     TCH TDELTA QLAT
00484     """
00485     type = 'MAT4'
00486     def __init__(self, card=None, data=None):
00487         ThermalMaterial.__init__(self, card, data)
00488         if card:
00489             self.mid  = card.field(1)
00490             self.k    = card.field(2)
00491             self.cp   = card.field(3, 0.0)
00492             self.rho  = card.field(4, 1.0)
00493             self.H    = card.field(5)
00494             self.mu   = card.field(6)
00495             self.hgen = card.field(7, 1.0)
00496             self.refEnthalpy = card.field(8)
00497             self.tch    = card.field(9)
00498             self.tdelta = card.field(10)
00499             self.qlat   = card.field(11)
00500         else:
00501             self.mid  = data[0]
00502             self.k    = data[1]
00503             self.cp   = data[2]
00504             self.rho  = data[3]
00505             self.H    = data[4]
00506             self.mu   = data[5]
00507             self.hgen = data[6]
00508             self.refEnthalpy = data[7]
00509             self.tch    = data[8]
00510             self.tdelta = data[9]
00511             self.qlat   = data[10]
00512         ###
00513 
00514     def rawFields(self):
00515         fields = ['MAT4', self.mid, self.k, self.cp, self.rho, self.H, self.mu, self.hgen, self.refEnthalpy,
00516                           self.tch, self.tdelta, self.qlat]
00517         return fields
00518 
00519     def reprFields(self):
00520         rho  = set_blank_if_default(self.rho, 1.0)
00521         hgen = set_blank_if_default(self.hgen, 1.0)
00522         cp   = set_blank_if_default(self.cp, 0.0)
00523         fields = ['MAT4', self.mid, self.k, cp, rho, self.H, self.mu, hgen, self.refEnthalpy,
00524                           self.tch, self.tdelta, self.qlat]
00525         return fields
00526 
00527 class MAT5(ThermalMaterial):  # also AnisotropicMaterial
00528     """
00529     Defines the thermal material properties for anisotropic materials.
00530 
00531     MAT5 MID KXX KXY KXZ KYY KYZ KZZ CP
00532     RHO HGEN
00533     """
00534     type = 'MAT5'
00535     def __init__(self, card=None, data=None):
00536         ThermalMaterial.__init__(self, card, data)
00537         if card:
00538             self.mid  = card.field(1)
00539             ## Thermal conductivity (assumed default=0.0)
00540             self.kxx  = card.field(2, 0.)
00541             self.kxy  = card.field(3, 0.)
00542             self.kxz  = card.field(4, 0.)
00543             self.kyy  = card.field(5, 0.)
00544             self.kyz  = card.field(6, 0.)
00545             self.kzz  = card.field(7, 0.)
00546 
00547             self.cp   = card.field(8, 0.0)
00548             self.rho  = card.field(9, 1.0)
00549             self.hgen = card.field(10, 1.0)
00550         else:
00551             self.mid  = data[0]
00552             self.kxx  = data[1]
00553             self.kxy  = data[2]
00554             self.kxz  = data[3]
00555             self.kyy  = data[4]
00556             self.kyz  = data[5]
00557             self.kzz  = data[6]
00558             self.cp   = data[7]
00559             self.rho  = data[8]
00560             self.hgen = data[9]
00561         ###
00562 
00563     def K(self):
00564         """
00565         thermal conductivity matrix
00566         """
00567         k = array([[self.kxx, self.kxy, self.kxz],
00568                    [self.kxy, self.kyy, self.kyz],
00569                    [self.kxz, self.kyz, self.kzz]])
00570         return k
00571 
00572     def rawFields(self):
00573         fields = ['MAT5', self.mid, self.kxx, self.kxy, self.kxz, self.kyy, self.kyz, self.kzz, self.cp,
00574                           self.rho, self.hgen]
00575         return fields
00576 
00577     def reprFields(self):
00578         kxx  = set_blank_if_default(self.kxx, 0.0)
00579         kyy  = set_blank_if_default(self.kyy, 0.0)
00580         kzz  = set_blank_if_default(self.kzz, 0.0)
00581         kxy  = set_blank_if_default(self.kxy, 0.0)
00582         kyz  = set_blank_if_default(self.kyz, 0.0)
00583         kxz  = set_blank_if_default(self.kxz, 0.0)
00584 
00585         rho  = set_blank_if_default(self.rho, 1.0)
00586         hgen = set_blank_if_default(self.hgen, 1.0)
00587         cp   = set_blank_if_default(self.cp,  0.0)
00588         fields = ['MAT5', self.mid, kxx, kxy, kxz, kyy, kyz, kzz, cp,
00589                          rho, hgen]
00590         return fields
00591 
00592 class MAT8(AnisotropicMaterial):
00593     """
00594     Defines the material property for an orthotropic material for isoparametric
00595     shell elements.
00596     MAT8          10  1.25+7  9.75+6     .28  1.11+7                   2.4-2
00597     """
00598     type = 'MAT8'
00599     def __init__(self, card=None, data=None):
00600         AnisotropicMaterial.__init__(self, card, data)
00601         if card:
00602             self.mid  = card.field(1)
00603             self.e11  = card.field(2)  ## @todo is this the correct default
00604             self.e22  = card.field(3)  ## @todo is this the correct default
00605             self.nu12 = card.field(4)  ## @todo is this the correct default
00606 
00607             self.g12  = card.field(5, 0.0)
00608             self.g1z  = card.field(6, 1e8)
00609             self.g2z  = card.field(7, 1e8)
00610             self.rho  = card.field(8, 0.0)
00611             self.a1   = card.field(9, 0.0)
00612             self.a2   = card.field(10, 0.0)
00613             self.TRef = card.field(11, 0.0)
00614             self.Xt   = card.field(12, 0.0)
00615             self.Xc   = card.field(13, self.Xt)
00616             self.Yt   = card.field(14, 0.0)
00617             self.Yc   = card.field(15, self.Yt)
00618             self.S    = card.field(16, 0.0)
00619             self.ge   = card.field(17, 0.0)
00620             self.F12  = card.field(18, 0.0)
00621             self.strn = card.field(19, 0.0)
00622         else:
00623             self.mid  = data[0]
00624             self.e11  = data[1]
00625             self.e22  = data[2]
00626             self.nu12 = data[3]
00627 
00628             self.g12  = data[4]
00629             self.g1z  = data[5]
00630             self.g2z  = data[6]
00631             self.rho  = data[7]
00632             self.a1   = data[8]
00633             self.a2   = data[9]
00634             self.TRef = data[10]
00635             self.Xt   = data[11]
00636             self.Xc   = data[12]
00637             self.Yt   = data[13]
00638             self.Yc   = data[14]
00639             self.S    = data[15]
00640             self.ge   = data[16]
00641             self.F12  = data[17]
00642             self.strn = data[18]
00643 
00644     def E11(self):
00645         return self.e11
00646     def E22(self):
00647         return self.e22
00648     def Nu12(self):
00649         return self.nu12
00650     def G12(self):
00651         return self.g12
00652     
00653     def D(self):
00654         """
00655         @todo what about G1z and G2z
00656         """
00657         E11  = self.E11()
00658         E22  = self.E22()
00659         nu12 = self.Nu12()
00660         G12  = self.G12()
00661 
00662         D = zeros((3, 3))
00663         mu = 1.-nu12*nu12*E11/E22    # not necessary b/c they're equal
00664         D[0, 0] = E11/mu
00665         D[1, 1] = E22/mu
00666         D[0, 1] = nu12*D[0, 0]
00667         D[1, 0] = D[0, 1]
00668         D[2, 2] = G12
00669         
00670         return D
00671 
00672     def rawFields(self):
00673         fields = ['MAT8', self.mid, self.e11, self.e22, self.nu12, self.g12, self.g1z, self.g2z, self.rho,
00674                   self.a1, self.a2, self.TRef, self.Xt, self.Xc, self.Yt, self.Yc, self.S,
00675                   self.ge, self.F12, self.strn]
00676         return fields
00677 
00678     def reprFields(self):
00679         G12  = set_blank_if_default(self.g12, 0.)
00680         G1z  = set_blank_if_default(self.g1z, 1e8)
00681         G2z  = set_blank_if_default(self.g2z, 1e8)
00682 
00683         rho  = set_blank_if_default(self.rho, 0.0)
00684         a1   = set_blank_if_default(self.a1,  0.0)
00685         a2   = set_blank_if_default(self.a2,  0.0)
00686         TRef = set_blank_if_default(self.TRef, 0.0)
00687 
00688         Xt   = set_blank_if_default(self.Xt, 0.)
00689         Yt   = set_blank_if_default(self.Yt, 0.)
00690 
00691         Xc   = set_blank_if_default(self.Xc, self.Xt)
00692         Yc   = set_blank_if_default(self.Yc, self.Yt)
00693         
00694         S    = set_blank_if_default(self.S,   0.0)
00695         ge   = set_blank_if_default(self.ge,  0.0)
00696         F12  = set_blank_if_default(self.F12, 0.0)
00697         strn = set_blank_if_default(self.strn, 0.0)
00698         
00699         fields = ['MAT8', self.mid, self.e11, self.e22, self.nu12, G12, G1z, G2z, rho,
00700                   a1, a2, TRef, Xt, Xc, Yt, Yc, S,
00701                   ge, F12, strn]
00702         return fields
00703 
00704 class MAT9(AnisotropicMaterial):
00705     """
00706     Defines the material properties for linear, temperature-independent,
00707     anisotropic materials for solid isoparametric elements (see PSOLID entry
00708     description).
00709 
00710     MAT9 MID G11 G12 G13 G14 G15 G16 G22
00711     G23 G24 G25 G26 G33 G34 G35 G36
00712     G44 G45 G46 G55 G56 G66 RHO A1
00713     A2 A3 A4 A5 A6 TREF GE
00714     """
00715     type = 'MAT9'
00716     def __init__(self, card=None, data=None):
00717         AnisotropicMaterial.__init__(self, card, data)
00718         if card:
00719             self.mid = card.field(1)
00720             self.G11 = card.field(2, 0.0)
00721             self.G12 = card.field(3, 0.0)
00722             self.G13 = card.field(4, 0.0)
00723             self.G14 = card.field(5, 0.0)
00724             self.G15 = card.field(6, 0.0)
00725             self.G16 = card.field(7, 0.0)
00726             self.G22 = card.field(8, 0.0)
00727             self.G23 = card.field(9, 0.0)
00728             self.G24 = card.field(10, 0.0)
00729             self.G25 = card.field(11, 0.0)
00730             self.G26 = card.field(12, 0.0)
00731             self.G33 = card.field(13, 0.0)
00732             self.G34 = card.field(14, 0.0)
00733             self.G35 = card.field(15, 0.0)
00734             self.G36 = card.field(16, 0.0)
00735             self.G44 = card.field(17, 0.0)
00736             self.G45 = card.field(18, 0.0)
00737             self.G46 = card.field(19, 0.0)
00738             self.G55 = card.field(20, 0.0)
00739             self.G56 = card.field(21, 0.0)
00740             self.G66 = card.field(22, 0.0)
00741             self.rho = card.field(23, 0.0)
00742             self.A   = card.fields(24, 30, [0.]*6)
00743             self.TRef = card.field(30, 0.0)
00744             self.ge   = card.field(31, 0.0)
00745         else:
00746             self.mid = data[0]
00747             self.G11 = data[1][0]
00748             self.G12 = data[1][1]
00749             self.G13 = data[1][2]
00750             self.G14 = data[1][3]
00751             self.G15 = data[1][4]
00752             self.G16 = data[1][5]
00753             self.G22 = data[1][6]
00754             self.G23 = data[1][7]
00755             self.G24 = data[1][8]
00756             self.G25 = data[1][9]
00757             self.G26 = data[1][10]
00758             self.G33 = data[1][11]
00759             self.G34 = data[1][12]
00760             self.G35 = data[1][13]
00761             self.G36 = data[1][14]
00762             self.G44 = data[1][15]
00763             self.G45 = data[1][16]
00764             self.G46 = data[1][17]
00765             self.G55 = data[1][18]
00766             self.G56 = data[1][19]
00767             self.G66 = data[1][20]
00768             self.rho = data[2]
00769             self.A   = data[3]
00770             self.TRef = data[4]
00771             self.ge   = data[5]
00772         ###
00773         assert len(self.A)==6
00774             
00775     def D(self):
00776         D = array([[self.G11, self.G12, self.G13, self.G14, self.G15, self.G16],
00777                    [self.G12, self.G22, self.G23, self.G24, self.G25, self.G26],
00778                    [self.G13, self.G23, self.G33, self.G34, self.G35, self.G36],
00779                    [self.G14, self.G24, self.G34, self.G44, self.G45, self.G46],
00780                    [self.G15, self.G25, self.G35, self.G45, self.G55, self.G56],
00781                    [self.G16, self.G26, self.G36, self.G46, self.G56, self.G66]])
00782         return D
00783 
00784     def rawFields(self):
00785         fields = ['MAT9', self.mid, self.G11, self.G12, self.G13, self.G14, self.G15, self.G16, self.G22,
00786                           self.G23, self.G24, self.G25, self.G26, self.G33, self.G34, self.G35, self.G36,
00787                           self.G44, self.G45, self.G46, self.G55, self.G56, self.G66, self.rho]+self.A+[self.TRef, self.ge]
00788         return fields
00789 
00790     def reprFields(self):
00791         A = []
00792         for a in self.A:
00793             a = set_blank_if_default(a, 0.0)
00794             A.append(a)
00795 
00796         rho  = set_blank_if_default(self.rho, 0.0)
00797         TRef = set_blank_if_default(self.TRef, 0.0)
00798         ge   = set_blank_if_default(self.ge, 0.0)
00799         fields = ['MAT9', self.mid, self.G11, self.G12, self.G13, self.G14, self.G15, self.G16, self.G22,
00800                           self.G23, self.G24, self.G25, self.G26, self.G33, self.G34, self.G35, self.G36,
00801                           self.G44, self.G45, self.G46, self.G55, self.G56, self.G66, rho]+A+[TRef,ge]
00802         return fields
00803 
00804 class MAT10(Material):
00805     """
00806     Defines material properties for fluid elements in coupled fluid-structural
00807     analysis.
00808     MAT10 MID BULK RHO C GE
00809     """
00810     type = 'MAT10'
00811     def __init__(self, card=None, data=None):
00812         Material.__init__(self, card, data)
00813         if card:
00814             self.mid = card.field(1)
00815             self.getBulkRhoC(card)
00816             self.ge = card.field(5, 0.0)
00817         else:
00818             self.mid  = data[0]
00819             self.bulk = data[1]
00820             self.rho  = data[2]
00821             self.c    = data[3]
00822             self.ge   = data[4]
00823         ###
00824 
00825     def getBulkRhoC(self, card):
00826         """
00827         \f[ \large bulk = c^2 \rho \f]
00828         """
00829         bulk = card.field(2)
00830         rho  = card.field(3)
00831         c    = card.field(4)
00832 
00833         if c is not None:
00834             if rho is not None:
00835                 bulk = c**2.*rho
00836             elif bulk is not None:
00837                 rho = bulk/c**2.
00838             else:
00839                 msg = 'c is the only card defined on tbe MAT10'
00840                 raise RuntimeError(msg)
00841         elif bulk is not None:
00842             if rho is not None:
00843                 c = (bulk/rho)**0.5
00844             else:
00845                 msg = 'c, bulk, and rho are all undefined on tbe MAT10'
00846                 raise RuntimeError(msg)
00847             ###
00848         else:
00849             msg = 'c, bulk, and rho are all undefined on tbe MAT10'
00850             raise RuntimeError(msg)
00851         ###
00852         self.bulk = bulk
00853         self.rho = rho
00854         self.c = c
00855 
00856     def rawFields(self):
00857         fields = ['MAT10', self.mid, self.bulk, self.rho, self.c, self.ge]
00858         return fields
00859 
00860     def reprFields(self):
00861         ge = set_blank_if_default(self.ge, 0.0)
00862         fields = ['MAT10', self.mid, self.bulk, self.rho, self.c, ge]
00863         return fields
00864        
00865 
00866 class MATHP(HyperelasticMaterial):
00867     def __init__(self, card=None, data=None):
00868         HyperelasticMaterial.__init__(self, card, data)
00869         if card:
00870             self.mid  = card.field(1)
00871             self.a10  = card.field(2, 0.) 
00872             self.a01  = card.field(3, 0.) 
00873             self.d1   = card.field(4, (self.a10+self.a01)*1000)
00874             self.rho  = card.field(5, 0.)
00875             self.av   = card.field(6, 0.)
00876             self.TRef = card.field(7, 0.)
00877             self.ge   = card.field(8, 0.)
00878 
00879             self.na   = card.field(10, 1)
00880             self.nd   = card.field(11, 1)
00881 
00882             self.a20  = card.field(17, 0.)
00883             self.a11  = card.field(18, 0.)
00884             self.a02  = card.field(19, 0.)
00885             self.d2   = card.field(20, 0.)
00886 
00887             self.a30 = card.field(25, 0.)
00888             self.a21 = card.field(26, 0.)
00889             self.a12 = card.field(27, 0.)
00890             self.a03 = card.field(28, 0.)
00891             self.d3  = card.field(29, 0.)
00892 
00893             self.a40 = card.field(33, 0.)
00894             self.a31 = card.field(34, 0.)
00895             self.a22 = card.field(35, 0.)
00896             self.a13 = card.field(36, 0.)
00897             self.a04 = card.field(37, 0.)
00898             self.d4  = card.field(38, 0.)
00899 
00900             self.a50 = card.field(41, 0.)
00901             self.a41 = card.field(42)
00902             self.a32 = card.field(43)
00903             self.a23 = card.field(44)
00904             self.a14 = card.field(45)
00905             self.a05 = card.field(46)
00906             self.d5  = card.field(47, 0.)
00907 
00908             self.tab1 = card.field(49)
00909             self.tab2 = card.field(50)
00910             self.tab3 = card.field(51)
00911             self.tab4 = card.field(52)
00912             self.tabd = card.field(56)
00913         else:
00914             main = data[0]
00915             (mid, a10, a01, d1, rho, av, alpha, tref, ge, sf, na, nd, kp,
00916              a20, a11, a02, d2,
00917              a30, a21, a12, a03, d3,
00918              a40, a31, a22, a13, a04, d4,
00919              a50, a41, a32, a23, a14, a05, d5,
00920              continueFlag) = main
00921 
00922             self.mid  = mid
00923             self.a10  = a10
00924             self.a01  = a01
00925             self.d1   = d1
00926             self.rho  = rho
00927             self.av   = av
00928             self.TRef = tref
00929             self.ge   = ge
00930 
00931             self.na   = na
00932             self.nd   = nd
00933 
00934             self.a20  = a20
00935             self.a11  = a11
00936             self.a02  = a02
00937             self.d2   = d2
00938 
00939             self.a30 = a30
00940             self.a21 = a21
00941             self.a12 = a12
00942             self.a03 = a03
00943             self.d3  = d3
00944 
00945             self.a40 = a40
00946             self.a31 = a31
00947             self.a22 = a22
00948             self.a13 = a13
00949             self.a04 = a04
00950             self.d4  = d4
00951 
00952             self.a50 = a50
00953             self.a41 = a41
00954             self.a32 = a32
00955             self.a23 = a23
00956             self.a14 = a14
00957             self.a05 = a05
00958             self.d5  = d5
00959 
00960             if continueFlag:
00961                 (tab1, tab2, tab3, tab4, x1, x2, x3, tab5) = data[1]
00962             else:
00963                 tab1 = None
00964                 tab2 = None
00965                 tab3 = None
00966                 tab4 = None
00967                 tab5 = None
00968             ###
00969             self.tab1 = tab1
00970             self.tab2 = tab2
00971             self.tab3 = tab3
00972             self.tab4 = tab4
00973             self.tabd = tab5
00974 
00975     def rawFields(self):
00976         fields = ['MATHP', self.mid, self.a10, self.a01, self.d1, self.rho, self.av, self.TRef, self.ge,
00977                        None, self.na,  self.nd,      None,     None,    None,     None, None,
00978                    self.a20, self.a11, self.a02,  self.d2,     None,    None,     None, None,
00979                    self.a30, self.a21, self.a12, self.a03,  self.d3,    None,     None, None,
00980                    self.a40, self.a31, self.a22, self.a13, self.a04, self.d4,     None, None,
00981                    self.a50, self.a41, self.a32, self.a23, self.a14, self.a05, self.d5, None,
00982                    self.tab1, self.tab2, self.tab4, None, None, None, self.tabd]
00983         return fields
00984 
00985     def reprFields(self):
00986         av = set_blank_if_default(self.av, 0.0)
00987         na = set_blank_if_default(self.na, 0.0)
00988         nd = set_blank_if_default(self.nd, 0.0)
00989 
00990         a01 = set_blank_if_default(self.a01, 0.0)
00991         a10 = set_blank_if_default(self.a10, 0.0)
00992         d1  = set_blank_if_default(self.d1, 1000*(self.a01+self.a10))
00993 
00994         a20 = set_blank_if_default(self.a20, 0.0)
00995         a11 = set_blank_if_default(self.a11, 0.0)
00996         a02 = set_blank_if_default(self.a02, 0.0)
00997         d2  = set_blank_if_default(self.d2, 0.0)
00998 
00999         a30 = set_blank_if_default(self.a30, 0.0)
01000         a12 = set_blank_if_default(self.a12, 0.0)
01001         a21 = set_blank_if_default(self.a21, 0.0)
01002         a03 = set_blank_if_default(self.a03, 0.0)
01003         d3  = set_blank_if_default(self.d3, 0.0)
01004 
01005         a40 = set_blank_if_default(self.a40, 0.0)
01006         a31 = set_blank_if_default(self.a31, 0.0)
01007         a22 = set_blank_if_default(self.a22, 0.0)
01008         a13 = set_blank_if_default(self.a13, 0.0)
01009         a04 = set_blank_if_default(self.a04, 0.0)
01010         d4  = set_blank_if_default(self.d4, 0.0)
01011 
01012         a50 = set_blank_if_default(self.a50, 0.0)
01013         a41 = set_blank_if_default(self.a41, 0.0)
01014         a32 = set_blank_if_default(self.a32, 0.0)
01015         a23 = set_blank_if_default(self.a23, 0.0)
01016         a14 = set_blank_if_default(self.a14, 0.0)
01017         a05 = set_blank_if_default(self.a05, 0.0)
01018         d5  = set_blank_if_default(self.d5, 0.0)
01019 
01020         TRef = set_blank_if_default(self.TRef, 0.0)
01021         ge   = set_blank_if_default(self.ge, 0.0)
01022         fields = ['MATHP', self.mid, a10, a01, d1, self.rho, av, TRef, ge,
01023                           None, na, nd,  None, None, None, None, None,
01024                           a20, a11, a02, d2,   None, None, None, None,
01025                           a30, a21, a12, a03,  d3,   None, None, None,
01026                           a40, a31, a22, a13,  a04,  d4,   None, None,
01027                           a50, a41, a32, a23,  a14,  a05,  d5,   None,
01028                           self.tab1, self.tab2, self.tab3, self.tab4, None, None, None, self.tabd]
01029         return fields
01030 
01031 class MaterialDependence(BaseCard):
01032     def __init__(self, card, data):
01033         pass
01034 
01035 class MATS1(MaterialDependence):
01036     """
01037     Specifies stress-dependent material properties for use in applications
01038     involving nonlinear materials. This entry is used if a MAT1, MAT2 or MAT9
01039     entry is specified with the same MID in a nonlinear solution sequence
01040     (SOLs 106 and 129).
01041     """
01042     type = 'MATS1'
01043     def __init__(self, card=None, data=None):
01044         MaterialDependence.__init__(self, card, data)
01045         if card:
01046             ## Identification number of a MAT1, MAT2, or MAT9 entry.
01047             self.mid  = card.field(1)
01048             ## Identification number of a TABLES1 or TABLEST entry. If H is
01049             ## given, then this field must be blank.
01050             self.tid  = card.field(2)
01051             ## Type of material nonlinearity. ('NLELAST' for nonlinear elastic 
01052             ## or 'PLASTIC' for elastoplastic.)
01053             self.Type = card.field(3)
01054             ## Work hardening slope (slope of stress versus plastic strain) in
01055             ## units of stress. For elastic-perfectly plastic cases, H=0.0.
01056             ## For more than a single slope in the plastic range, the
01057             ## stress-strain data must be supplied on a TABLES1 entry referenced
01058             ## by TID, and this field must be blank
01059             self.h    = card.field(4)
01060             ## Yield function criterion, selected by one of the following values
01061             ## (1) Von Mises (2) Tresca (3) Mohr-Coulomb (4) Drucker-Prager
01062             self.yf   = card.field(5, 1)
01063             ## Hardening Rule, selected by one of the following values
01064             ## (Integer): (1) Isotropic (Default) (2) Kinematic
01065             ## (3) Combined isotropic and kinematic hardening
01066             self.hr   = card.field(6, 1)
01067             ## Initial yield point
01068             self.limit1 = card.field(7)
01069             ## Internal friction angle, measured in degrees, for the
01070             ## Mohr-Coulomb and Drucker-Prager yield criteria
01071             self.limit2 = card.field(8)
01072         else:
01073             (mid, tid, Type, h, yf, hr, limit1, limit2) = data
01074             self.mid = mid
01075             self.tid = tid
01076             if Type == 1:
01077                 self.Type = 'NLELAST'
01078             elif Type == 2:
01079                 self.Type = 'PLASTIC'
01080             else:
01081                 raise RuntimeError('invalid Type:  Type=%s; must be 1=NLELAST or 2=PLASTIC' % (Type))
01082             self.h  = h
01083             self.yf = yf
01084             self.hr = hr
01085             self.limit1 = limit1
01086             self.limit2 = limit2
01087         ###
01088 
01089     def Yf(self):
01090         d = {1:'VonMises', 2:'Tresca', 3:'MohrCoulomb', 4:'Drucker-Prager'}
01091         return d[self.yf]
01092 
01093     def Hf(self):
01094         d = {1:'Isotropic', 2:'Kinematic', 3:'Combined'}
01095         return d[self.hr]
01096 
01097     def E(self, strain=None):
01098         """
01099         Gets E (Young's Modulus) for a given strain
01100         @param self the object pointer
01101         @param strain the strain (None -> linear E value)
01102         @retval E (Young's Modulus)
01103         """
01104         msg = "E (Young's Modulus) not implemented for MATS1"
01105         raise NotImplementedError(msg)
01106         if self.tid:
01107             E = self.tid.Value(strain)
01108         ###
01109         return E
01110 
01111     def crossReference(self, model):
01112         self.mid = model.Material(self.mid)
01113         if self.tid: # then self.h is used
01114             self.tid = model.Table(self.tid)
01115         ###
01116 
01117     def Mid(self):
01118         if isinstance(self.mid, int):
01119             return self.mid
01120         return self.mid.mid
01121 
01122     def Tid(self):
01123         if isinstance(self.tid, Table):
01124             return self.tid.tid
01125         return self.tid
01126 
01127     def rawFields(self):
01128         fields = ['MATS1', self.Mid(), self.Tid(), self.Type, self.h, self.yf, self.hr, self.limit1, self.limit2]
01129         return fields
01130 
01131     def reprFields(self):
01132         return self.rawFields()
01133     
 All Classes Namespaces Files Functions Variables