pyNastran
0.5.0
pyNastran BDF Reader/Writer, OP2 Parser, and GUI
|
00001 ## GNU Lesser General Public License 00002 ## 00003 ## Program pyNastran - a python interface to NASTRAN files 00004 ## Copyright (C) 2011-2012 Steven Doyle, Al Danial 00005 ## 00006 ## Authors and copyright holders of pyNastran 00007 ## Steven Doyle <mesheb82@gmail.com> 00008 ## Al Danial <al.danial@gmail.com> 00009 ## 00010 ## This file is part of pyNastran. 00011 ## 00012 ## pyNastran is free software: you can redistribute it and/or modify 00013 ## it under the terms of the GNU Lesser General Public License as published by 00014 ## the Free Software Foundation, either version 3 of the License, or 00015 ## (at your option) any later version. 00016 ## 00017 ## pyNastran is distributed in the hope that it will be useful, 00018 ## but WITHOUT ANY WARRANTY; without even the implied warranty of 00019 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00020 ## GNU General Public License for more details. 00021 ## 00022 ## You should have received a copy of the GNU Lesser General Public License 00023 ## along with pyNastran. If not, see <http://www.gnu.org/licenses/>. 00024 ## 00025 # 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